/*
 *
 Copyright (c) 2001-2016 泛微软件.
 * 泛微协同商务系统,版权所有.
 * 
 */
package weaver.fna.invoice.common;

import java.io.*;
import java.security.MessageDigest;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.JspWriter;


import com.api.doc.detail.service.DocSaveService;
import com.engine.fna.util.FnaTakeOneNoteCostTypeUtil;
import com.engine.personalIncomeTax.biz.RecordsBiz;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import com.cloudstore.dev.api.util.APPManager;

//import b.a.a.ac.r;

import org.apache.commons.codec.binary.Base64;

import net.coobird.thumbnailator.Thumbnails;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import weaver.conn.BatchRecordSet;
import weaver.conn.RecordSet;
import weaver.file.ImageFileManager;
import weaver.fna.e9.po.base.FnaInvoiceLedger;
import weaver.fna.general.FnaCommon;
import weaver.fna.general.FnaLogSqlUtil;
import weaver.fna.invoice.entity.FnaInvoiceInterface;
import weaver.fna.invoice.entity.FnaInvoiceLedgerDetail;
import weaver.fna.invoice.interfaces.baiwang.FnaBaiwangOpenApi;
import weaver.fna.invoice.sdk.SdkInvoiceUtil;
import weaver.fna.invoice.utils.*;
import weaver.general.BaseBean;
import weaver.general.ThreadVarLanguage;
import weaver.general.Util;
import weaver.hrm.User;
import weaver.hrm.company.DepartmentComInfo;
import weaver.hrm.company.SubCompanyComInfo;
import weaver.hrm.resource.ResourceBelongtoComInfo;
import weaver.hrm.resource.ResourceComInfo;
import weaver.sm.SM4Utils;
import weaver.systeminfo.SystemEnv;


/**
 * 发票公共处理类
 *
 */
@SuppressWarnings({ "rawtypes", "deprecation" })
public final class FnaInvoiceCommon extends BaseBean{

	//ea92aec4-45f2-4ef9-9fd6-b25000481ba4,password
	public static final String MDE_CODE = "WEAVER_39CE313C5FAAC649EF10269F69C06B3D";

	//56f3236a-a9c6-40b5-84e6-56749fba3012,client_secret
	public static final String MDE_CODE_CLIENT_SECRET = "WEAVER_FFC947EA939B3C5F74A53C8F0D9F99F5";

	//978c7c07-24f0-4a65-97aa-50f9d4f88ace,sqm
	public static final String MDE_CODE_SQM = "WEAVER_D8165D1FBC808F0DFE4016073A3A2A80";

	//de9a995f-79c5-43dc-b353-4a3f3f82ff6b,SM4加密密钥
	public static  String SM4 = "";
    static {
		getSM();
	}
	public static void  getSM(){
		//初始化前fnaEncryptInfo表中无数据，考虑老数据问题，如果fnainvoiceinterface表中有数据，使用老的加密方式，否则随机生成一个
		RecordSet rs = new RecordSet();
		SM4="";
		int sign=0;
		rs.executeQuery("select smkey,sign from fnaEncryptInfo");
		if(rs.next()){
			SM4 = Util.null2String(rs.getString("smkey"));
			sign = Util.getIntValue(rs.getString("sign"),0);
		}
		if(sign!=1){
			int cnt=0;
			rs.executeQuery("select count(id) cnt from fnainvoiceinterface");
			if(rs.next()){
				cnt = Util.getIntValue(rs.getString("cnt"),0);
			}
			if(cnt<=0) {
				SM4 = FnaCommon.getPrimaryKeyGuid1();
				rs.executeUpdate("update fnaEncryptInfo set smkey=?,sign=?",SM4,"1");
			}

		}
	}


	/** 金额格式化对象；保留两位小数*/
	DecimalFormat df = new DecimalFormat("####################################################0.00");

	/**来自微信*/
	public static final int INVOICESOURCE_WECHAT = 1;

	/**来自国信*/
	public static final int INVOICESOURCE_GUOXIN = 2;

	/**来自台帐*/
	public static final int INVOICESOURCE_TAIZHANG = 3;

	/**来自百望*/
	public static final int INVOICESOURCE_BAIWANG = 4;

	/**来自发票识别*/
	public static final int INVOICESOURCE_OCR = 5;

	/**来自发票识别*/
	public static final int INVOICESOURCE_EMAIL = 6;

	/**初始状态*/
	public static final int INIT_STATUS = 0;

	/**冻结状态*/
	public static final int LOCK_STATUS = 1;

	/**核销状态*/
	public static final int CLOSURE_STATUS = 2;

	/** 批量更新发票状态*/
	private String UPDATEINVOICESTATUS_URL = "https://qyapi.weixin.qq.com/cgi-bin/card/invoice/reimburse/updatestatusbatch?access_token=";

	/** 批量查询电子发票*/
	private String GETINVOICEINFOBATCH_URL = "https://qyapi.weixin.qq.com/cgi-bin/card/invoice/reimburse/getinvoiceinfobatch?access_token=";

	/** corpId 企业号ID*/
	private String corpId = "";

	/** 最大上传大小 2.5 * 1024 * 1024 */
	public static final double MAX_BYTES = 2.5 * 1000 * 1000;
	/** 最大上传大小 2.5 * 1024 * 1024 */
	public static final double MAX_BYTES_RQ = 8.0 * 1000 * 1000;
	/**压缩图片质量递减间隔*/
	private static final double DIMINISHING_INTERVAL = 0.5d;




	/**
	 * 错误信息
	 */
	private final static ConcurrentHashMap<String, String> CONCURRENT_HASH_MAP = new ConcurrentHashMap<String, String>();

	static{
		CONCURRENT_HASH_MAP.put("72015", ""+ SystemEnv.getHtmlLabelName(10003250,weaver.general.ThreadVarLanguage.getLang())+"");
		CONCURRENT_HASH_MAP.put("72017", ""+ SystemEnv.getHtmlLabelName(10003251,weaver.general.ThreadVarLanguage.getLang())+"");
		CONCURRENT_HASH_MAP.put("72023", ""+ SystemEnv.getHtmlLabelName(10003252,weaver.general.ThreadVarLanguage.getLang())+"/"+ SystemEnv.getHtmlLabelName(10003253,weaver.general.ThreadVarLanguage.getLang())+"/App"+ SystemEnv.getHtmlLabelName(10003254,weaver.general.ThreadVarLanguage.getLang())+"");
		CONCURRENT_HASH_MAP.put("72024", ""+ SystemEnv.getHtmlLabelName(10003255,weaver.general.ThreadVarLanguage.getLang())+"");
		CONCURRENT_HASH_MAP.put("72025", "wx_invoice_token "+ SystemEnv.getHtmlLabelName(2245,weaver.general.ThreadVarLanguage.getLang())+"");
		CONCURRENT_HASH_MAP.put("72028", ""+ SystemEnv.getHtmlLabelName(10003256,weaver.general.ThreadVarLanguage.getLang())+"");
		CONCURRENT_HASH_MAP.put("72029", ""+ SystemEnv.getHtmlLabelName(10003257,weaver.general.ThreadVarLanguage.getLang())+"");
		CONCURRENT_HASH_MAP.put("72030", "mchid "+ SystemEnv.getHtmlLabelName(2245,weaver.general.ThreadVarLanguage.getLang())+"");
		CONCURRENT_HASH_MAP.put("72031", ""+ SystemEnv.getHtmlLabelName(10003258,weaver.general.ThreadVarLanguage.getLang())+"");
		CONCURRENT_HASH_MAP.put("72035", ""+ SystemEnv.getHtmlLabelName(10003259,weaver.general.ThreadVarLanguage.getLang())+"order_id"+ SystemEnv.getHtmlLabelName(10003260,weaver.general.ThreadVarLanguage.getLang())+"order_id"+ SystemEnv.getHtmlLabelName(10003261,weaver.general.ThreadVarLanguage.getLang())+"");
		CONCURRENT_HASH_MAP.put("72036", ""+ SystemEnv.getHtmlLabelName(10003262,weaver.general.ThreadVarLanguage.getLang())+"");
		CONCURRENT_HASH_MAP.put("72038", ""+ SystemEnv.getHtmlLabelName(10003263,weaver.general.ThreadVarLanguage.getLang())+" appid 、"+ SystemEnv.getHtmlLabelName(10003264,weaver.general.ThreadVarLanguage.getLang())+" appid 、"+ SystemEnv.getHtmlLabelName(26738,weaver.general.ThreadVarLanguage.getLang())+" order_id "+ SystemEnv.getHtmlLabelName(386675,weaver.general.ThreadVarLanguage.getLang())+"");
		CONCURRENT_HASH_MAP.put("72039", ""+ SystemEnv.getHtmlLabelName(10003265,weaver.general.ThreadVarLanguage.getLang())+"");
		CONCURRENT_HASH_MAP.put("72040", "Pdf "+ SystemEnv.getHtmlLabelName(10003266,weaver.general.ThreadVarLanguage.getLang())+" pdf");
		CONCURRENT_HASH_MAP.put("72042", ""+ SystemEnv.getHtmlLabelName(10003267,weaver.general.ThreadVarLanguage.getLang())+"");
		CONCURRENT_HASH_MAP.put("72043", ""+ SystemEnv.getHtmlLabelName(10003268,weaver.general.ThreadVarLanguage.getLang())+"");
		CONCURRENT_HASH_MAP.put("72044", ""+ SystemEnv.getHtmlLabelName(10003269,weaver.general.ThreadVarLanguage.getLang())+"");
		CONCURRENT_HASH_MAP.put("40078", "card_id"+ SystemEnv.getHtmlLabelName(10003270,weaver.general.ThreadVarLanguage.getLang())+" "+ SystemEnv.getHtmlLabelName(10003271,weaver.general.ThreadVarLanguage.getLang())+" "+ SystemEnv.getHtmlLabelName(10003272,weaver.general.ThreadVarLanguage.getLang())+"card_id"+ SystemEnv.getHtmlLabelName(10003273,weaver.general.ThreadVarLanguage.getLang())+"");
	}

	/**
	 * 构造方法
	 */
	public FnaInvoiceCommon(){
		corpId = getPropValue("wechatElecInvoice_e9", "corpId").trim();
	}

	/**
	 * 发票代码校验
	 * @param invoiceCode
	 * @throws Exception
	 */
	public void checkInvoicecodeIflegal(String invoiceCode,int invoiceTypeSrc) throws Exception{
		int invoiceType = 0;
		if(invoiceCode.length() == 10){
			String eight = String.valueOf(invoiceCode.charAt(7));
			if("1".equals(eight) || "2".equals(eight) || "5".equals(eight) || "7".equals(eight)){
				invoiceType = 1;
			}else if("3".equals(eight) || "6".equals(eight)){
				invoiceType = 2;
			}
		}else if(invoiceCode.length() == 12){
			String first = String.valueOf(invoiceCode.charAt(0));
			String elevenTwelve = String.valueOf(invoiceCode.charAt(10)) + String.valueOf(invoiceCode.charAt(11));
			if("0".equals(first) && ("04".equals(elevenTwelve) || "05".equals(elevenTwelve) || "06".equals(elevenTwelve) || "07".equals(elevenTwelve)
					|| "11".equals(elevenTwelve) || "12".equals(elevenTwelve))){
				invoiceType = 2;
			}
		}
		//没有发票类型
		if(invoiceType == 0){
			throw new Exception("请输入正确的发票代码！");
		}
		//发票代码与发票类型不匹配
		if((invoiceTypeSrc == 1 && invoiceType == 1) || (invoiceTypeSrc == 2 && invoiceType == 2)){
			throw new Exception("请输入正确的发票代码！！");
		}
	}

	/**
	 * 新建或更新发票
	 * @param request
	 * @param response
	 * @param out
	 * @param user
	 */
	public void saveInvoice(HttpServletRequest request, HttpServletResponse response, JspWriter out, User user) throws Exception{
		String entryTime = Util.date(2);//录入时间
		int userid = user.getUID();
		int language = user.getLanguage();
		StringBuffer errorMsg = new StringBuffer();
		RecordSet rs = new RecordSet();
		BatchRecordSet brs = new BatchRecordSet();
		int currentid = Util.getIntValue(request.getParameter("id"),0);
		String billingDate = Util.null2String(request.getParameter("billingDate"));
		String invoiceCode = Util.null2String(request.getParameter("invoiceCode"));
		String invoiceNumber = Util.null2String(request.getParameter("invoiceNumber"));
		int invoiceType = Util.getIntValue(request.getParameter("invoiceType"));
		String checkCode = Util.null2String(request.getParameter("checkCode"));
		String seller = Util.null2String(request.getParameter("seller"));
		String purchaser = Util.null2String(request.getParameter("purchaser"));
		String purchaserTaxNo=Util.null2String(request.getParameter("purchaserTaxNo"));
		String salesTaxNo=Util.null2String(request.getParameter("salesTaxNo"));
		int indexnum = Util.getIntValue(request.getParameter("linkage_indexnum"));
		double priceWithoutTax = Util.getDoubleValue(request.getParameter("priceWithoutTax"),0.00);
		double tax = Util.getDoubleValue(request.getParameter("tax"),0.00);
		double taxIncludedPrice = Util.getDoubleValue(request.getParameter("taxIncludedPrice"),0.00);
		try {
			//校验invoiceCode发票代码
			Pattern pattern = Pattern.compile("[0-9]*");
			Matcher isNum = pattern.matcher(invoiceCode);
			if(!isNum.matches()){
				throw new Exception(SystemEnv.getHtmlLabelName(10000026, Util.getIntValue(language)));//XXX数据不正确
			}
			//存在10位和12位两种情况
			if(invoiceCode.length() != 10 && invoiceCode.length() != 12){
				throw new Exception(SystemEnv.getHtmlLabelName(10000026, Util.getIntValue(language))+"！");//XXX数据不正确
			}
			/**
			if(invoiceType == 1){//增值税普通发票
				//当位数为12位时，不需要判断，当位数为10位时需判断
				if(invoiceCode.length() == 10 && !invoiceCode.substring(invoiceCode.length()-2, invoiceCode.length()-1).equals("2")){
					throw new Exception(SystemEnv.getHtmlLabelName(10000026,weaver.general.Util.getIntValue(language))+"！！！");//XXX数据不正确
				}
			}else if(invoiceType == 2){//增值税专用发票
				if(invoiceCode.length() == 10 && !invoiceCode.substring(invoiceCode.length()-2, invoiceCode.length()-1).equals("3")){
					throw new Exception(SystemEnv.getHtmlLabelName(10000026,weaver.general.Util.getIntValue(language))+"！！！");//XXX数据不正确
				}
				if(invoiceCode.length() == 12){
					throw new Exception(SystemEnv.getHtmlLabelName(10000026,weaver.general.Util.getIntValue(language))+"！！！");//XXX数据不正确
				}
			}
			*/
			checkInvoicecodeIflegal(invoiceCode,invoiceType);
			//校验invoiceNumber发票号码
			isNum = pattern.matcher(invoiceNumber);
			if(!isNum.matches()){
				throw new Exception(SystemEnv.getHtmlLabelName(10000027, Util.getIntValue(language)));//XXX数据不正确
			}
			if(invoiceNumber.length() != 8){
				throw new Exception(SystemEnv.getHtmlLabelName(10000027, Util.getIntValue(language))+"！！");//XXX数据不正确
			}
			String sql = "select * from FnaInvoiceLedger  where invoiceNumber = '"+invoiceNumber+"'";
			boolean flag = rs.execute(sql);
			if(!flag)throw new Exception(SystemEnv.getHtmlLabelName(10000018, Util.getIntValue(language)));//数据库错误！请联系管理员！
			int id = 0;
			String invoiceNo = "";
			if(rs.next()){
				id = Util.getIntValue(rs.getString("id"));
				invoiceNo = Util.null2String(rs.getString("invoiceNumber"));
			}
			if(id != 0 && currentid != id && invoiceNumber.equals(invoiceNo)){
				throw new Exception(SystemEnv.getHtmlLabelName(10000028, Util.getIntValue(language)).replace("#replaceString#", "【"+invoiceCode+"】【"+invoiceNumber+"】"));//XXX已存在！
			}
			//校验invoiceType发票类型
			if(invoiceType != 1 && invoiceType != 2 && invoiceType != 15 && invoiceType != 16 && invoiceType != 20){
				throw new Exception(SystemEnv.getHtmlLabelName(10000031, Util.getIntValue(language)));
			}
			//校验checkCode校验码
			if(invoiceType == 1){//普通发票校验，专用发票没有校验码
				if(checkCode == null){
					throw new Exception(SystemEnv.getHtmlLabelName(10000142,language));//XXX不能为空！
				}
				pattern = Pattern.compile("^[0-9]{20}$");
				Matcher matcher = pattern.matcher(checkCode.trim());
				if(!matcher.matches()){
					throw new Exception(SystemEnv.getHtmlLabelName(10000143,language));//XXX必须为长度是20的数字！
				}
			}
			//校验明细信息
			for(int i = 0;i<indexnum;i++){
				String _invoiceServiceYype = Util.null2String(request.getParameter("invoiceServiceYype_"+i));
				double _taxRate = Util.getDoubleValue(request.getParameter("taxRate_"+i),0.00);
				if("".equals(_invoiceServiceYype)){
					continue;
				}
				//判断税额是否是金额税率的乘积
				//金额税额都有可能为负数
//				if(_priceWithoutTax <= 0)throw new Exception(SystemEnv.getHtmlLabelNames("131493,130802",language)+"！");
				if(_taxRate < 0)throw new Exception(SystemEnv.getHtmlLabelName(10000037, Util.getIntValue(language))+"！");
//				if(_tax < 0)throw new Exception(SystemEnv.getHtmlLabelNames("131495,130802",language)+"！");
				//计算可能存在偏差，暂时不需要校验，待发票验证时校验
//				double tax1 = Util.getDoubleValue((_priceWithoutTax * (_taxRate / 100.0)+"").substring(0, ((_priceWithoutTax * (_taxRate / 100.0)+"").indexOf(".")+3)));
//				if(_tax != tax1)
//				throw new Exception(SystemEnv.getHtmlLabelNames("131517",language)+"！");

			}
			//保存发票主表信息
			if(currentid > 0){//更新发票
				String update = "update FnaInvoiceLedger set billingDate='"+StringEscapeUtils.escapeSql(billingDate)+"',"+
						" invoiceCode='"+StringEscapeUtils.escapeSql(invoiceCode)+"',"+
						" invoiceNumber='"+StringEscapeUtils.escapeSql(invoiceNumber)+"',"+
						" invoiceType='"+invoiceType+"',"+
						" checkCode='"+StringEscapeUtils.escapeSql(checkCode)+"',"+
						" seller='"+StringEscapeUtils.escapeSql(seller)+"',"+
						" purchaser='"+StringEscapeUtils.escapeSql(purchaser)+"',"+
						" purchaserTaxNo='"+StringEscapeUtils.escapeSql(purchaserTaxNo)+"',"+
						" salesTaxNo='"+StringEscapeUtils.escapeSql(salesTaxNo)+"',"+
						" priceWithoutTax = "+df.format(priceWithoutTax)+","+
						" tax = "+df.format(tax)+","+
						" taxIncludedPrice = "+df.format(taxIncludedPrice)+" "+
						" where id = "+currentid;
				rs.execute(update);
			}else{
				String insert = "insert into FnaInvoiceLedger(billingDate,invoiceCode,invoiceNumber,invoiceType,checkCode,seller,purchaser,purchaserTaxNo,salesTaxNo,priceWithoutTax,tax,taxIncludedPrice,authenticity"+
						",userid_new,invoiceSource_new,status,entryTime) values ("+
						"'"+StringEscapeUtils.escapeSql(billingDate)+"',"+
						"'"+StringEscapeUtils.escapeSql(invoiceCode)+"',"+
						"'"+StringEscapeUtils.escapeSql(invoiceNumber)+"',"+
						""+invoiceType+","+
						"'"+StringEscapeUtils.escapeSql(checkCode)+"',"+
						"'"+StringEscapeUtils.escapeSql(seller)+"',"+
						"'"+StringEscapeUtils.escapeSql(purchaser)+"',"+
						"'"+StringEscapeUtils.escapeSql(purchaserTaxNo)+"',"+
						"'"+StringEscapeUtils.escapeSql(salesTaxNo)+"',"+
						""+df.format(priceWithoutTax)+","+
						""+df.format(tax)+","+
						""+df.format(taxIncludedPrice)+","+
						""+0+","+
						""+userid+","+
						""+INVOICESOURCE_TAIZHANG+","+
						""+INIT_STATUS+","+
						"'"+entryTime+"'"+
						")";
				rs.execute(insert);
				sql = "select max(id) maxid from FnaInvoiceLedger";
				rs.execute(sql);
				int maxid = 0;
				if(rs.next()){
					maxid = Util.getIntValue(rs.getString("maxid"));
				}
				currentid = maxid;
			}

			String delete = "delete from FnaInvoiceLedgerDetail where mainid = "+currentid;
			rs.execute(delete);
			List<String> insertList = new ArrayList<String>();
			for(int i = 0;i<indexnum;i++){
				String _invoiceServiceYype = Util.null2String(request.getParameter("invoiceServiceYype_"+i));
				double _priceWithoutTax = Util.getDoubleValue(request.getParameter("priceWithoutTax_"+i),0.00);
				double _taxRate = Util.getDoubleValue(request.getParameter("taxRate_"+i),0.00);
				double _tax = Util.getDoubleValue(request.getParameter("tax_"+i),0.00);
				if("".equals(_invoiceServiceYype)){
					continue;
				}
				//保存发票明细
				if(currentid > 0){//更新发票
					insertList.add(currentid+"" + Util.getSeparator() + StringEscapeUtils.escapeSql(_invoiceServiceYype)+"" + Util.getSeparator()
							+df.format(_priceWithoutTax)+ Util.getSeparator()+df.format(_taxRate)+ Util.getSeparator()+df.format(_tax));
				}
			}
			brs.executeSqlBatch("insert into FnaInvoiceLedgerDetail(mainid,invoiceServiceYype,priceWithoutTax,taxRate,tax) VALUES (?,?,?,?,?)", insertList);
		} catch (Exception e) {
			errorMsg.append(e.getMessage());
		}
		JSONObject jsonObject = new JSONObject();
		if(errorMsg.length() > 0){
			jsonObject.put("code", false);
			jsonObject.put("msg", errorMsg.toString());
		}else{
			jsonObject.put("flag", true);
		}
		out.print(jsonObject.toString());
		response.flushBuffer();
	}

	/**
	 * 判断当前发票是否可以被批量验票
	 * @param id
	 * @return
	 */
	public String getInvoice_checkboxpopedom(String id){
		RecordSet rs = new RecordSet();
		String sql = "select requestid,checkStatus,invoiceType from FnaInvoiceLedger where id = "+id;
		rs.execute(sql);
		String requestid = "";
		int checkStatus = 0;
		int invoiceType = 0;
		while(rs.next()){
			requestid = Util.null2String(rs.getString("requestid"));
			checkStatus = Util.getIntValue(rs.getString("checkStatus"));
			invoiceType = Util.getIntValue(rs.getString("invoiceType"));
		}
		if(!"".equals(requestid) || checkStatus == 1 || (invoiceType != 1 && invoiceType != 2 && invoiceType != 15 && invoiceType != 20 && invoiceType != 16))return "false";
		return "true";
	}

	/**
     * 判断当前的企业名称和企业纳税人识别号是否为接口所有，如果是则不可以被删除，如果是发票所有，则可以删除
     * @param type
     * @return
     */
	public String getCompanyAndTaxpayerNumber_checkboxpopedom(String type){
		if("1".equals(type)){
			return "false";
		}else{
			return "true";
		}
	}

	/**
	 * 判断当前发票是否可以被删除或者验票
	 * @param id 删除、编辑、查看、打印
	 * @return
	 */
	public List<String> getInvoice_popedom(String id,String otherParams){
		String[] otherParamArray = otherParams.split("\\+");
		String ifExistsInterface = otherParamArray[0];
		int userid = Util.getIntValue(otherParamArray[1], 0);
		String canEditAll = otherParamArray[2];

		//获取requestId
		int requestid = getRequestIdByInvoice(id);

		RecordSet rs = new RecordSet();
		List<String> resultList = new ArrayList<String>();
		rs.executeQuery("select checkStatus,invoiceType from FnaInvoiceLedger where id=?",id);
		int checkStatus = 0;
		int invoiceType = 0;
		while(rs.next()){
			checkStatus = Util.getIntValue(rs.getString("checkStatus"),0);
			invoiceType =  Util.getIntValue(rs.getString("invoiceType"),0);
		}
		if(requestid>0){
			resultList.add("false");
			resultList.add("false");
			resultList.add("true");
		}else if(checkStatus == 1){
			resultList.add("true");
			resultList.add("false");
			resultList.add("true");
		}else{
			resultList.add("true");
			resultList.add("true");
			resultList.add("false");
		}
		if((invoiceType==1 || invoiceType==2  || invoiceType==15 || invoiceType==20) && checkStatus == 1){
			resultList.add("true");
		}else{
			resultList.add("false");
		}
		resultList.add("true");
		resultList.add("true");


		//判断某个人是否仅仅只是个共享人
		if (userid != 1 && !Boolean.parseBoolean(canEditAll)) {      //能查看所有他就不仅仅是个共享人
			boolean isOnlySharer = InvoiceSharerUtil.checkInvoiceShare(id, userid);
			if (isOnlySharer) {
				//依据上面的权限为主，如果上面权限可查看，则再加上当前限制（只有，查看，打印，导出，对应下标：2,3,4）
				for (int i = 0; i < resultList.size(); i++) {
					String isShow = resultList.get(i);
					if ("true".equals(isShow)) {
						if (i != 2 && i != 3 && i != 4) {
							resultList.set(i, "false");
						}
					}
				}
			}
		}

		return resultList;
	}

	/**
	 * 获取发票requestid
	 * @param invoiceId
	 * @return
	 */
	public static int getRequestIdByInvoice(String invoiceId){
		RecordSet rs = new RecordSet();
		int requestid=0;
		rs.executeQuery("select requestid from FnaInvoiceLedger where id=?",invoiceId);
		if(rs.next()){
			requestid =Util.getIntValue(rs.getString("requestid"),0);
		}
		if(requestid<=0){
			rs.executeQuery("select requestid from fnaInvoiceReimbursement where mainid=?",invoiceId);
			if(rs.next()){
				requestid =Util.getIntValue(rs.getString("requestid"),0);
			}
		}
		return requestid;
	}


	/**
	 * 发票是否可以删除
	 * @param invoiceIds
	 * @return
	 */
	public static String canDeleteInvoice(boolean canEditAll,User user,String invoiceIds){
		String msg  = "";
		try{
			RecordSet rsQuery = FnaInvoiceCommon.executeInSql("select count(id) cnt from fnaInvoiceLedger where requestId>0 and id in(占位符标识)", invoiceIds, "executeQuery");
			if (rsQuery.next()){
				int cnt = Util.getIntValue(rsQuery.getString("cnt"));
				if(cnt>0) {
					throw new Exception(SystemEnv.getHtmlLabelName(529701,user.getLanguage()));
				}
			}

			RecordSet rs2Query = FnaInvoiceCommon.executeInSql("select count(id) cnt from fnaInvoiceReimbursement where requestId>0  and mainid in(占位符标识)", invoiceIds, "executeQuery");
			if (rs2Query.next()){
				int cnt = Util.getIntValue(rs2Query.getString("cnt"));
				if(cnt>0) {
					throw new Exception(SystemEnv.getHtmlLabelName(529701,user.getLanguage()));
				}
			}

			if(!canEditAll){
				RecordSet rs3Query = FnaInvoiceCommon.executeInSql("select userId_new from fnaInvoiceLedger where  id in(占位符标识)", invoiceIds, "executeQuery");
				while (rs3Query.next()){
					int userId_new = Util.getIntValue(rs3Query.getString("userId_new"));
					if(userId_new!=user.getUID()) {
						throw new Exception(SystemEnv.getHtmlLabelName(2012,user.getLanguage()));
					}
				}
			}
		}catch (Exception e){
			msg = e.getMessage();
		}
		return msg;
	}

	/**
	 * 如果当前企业名称和纳税人识别号属于查验接口，则不可以编辑和删除
	 * @param id
	 * @param type
	 * @return
	 */
    public List<String> getCompanyAndTaxpayerNumber_popedom(String id,String type){
        List<String> resultList = new ArrayList<String>();
        if("1".equals(type)){
            resultList.add("false");
            resultList.add("false");
            resultList.add("true");
        }else{
            resultList.add("true");
            resultList.add("true");
            resultList.add("true");
        }
        return resultList;
    }
	/**
	 * 判断当前记录是否生效或关闭
	 * @param id
	 * @param para
	 * @return
	 */
	public List<String> getInterface_popedom(String id,String para){
		RecordSet rs = new RecordSet();
		List<String> resultList = new ArrayList<String>();
		String sql = "select status,interfaceType from fnainvoiceinterface where id = "+id;
		rs.execute(sql);
		int status = 0;
		int interfaceType=-1;
		if(rs.next()){
			status = Util.getIntValue(rs.getString("status"),0);
			interfaceType = Util.getIntValue(rs.getString("interfaceType"),0);
		}
		resultList.add("true");
		if(interfaceType==2){
			resultList.add("false");
		}else{
			resultList.add("true");
		}

		resultList.add("false");
		resultList.add("false");

		if(interfaceType==1){
			resultList.add("true");
		}else{
			resultList.add("false");
		}
		return resultList;
	}

	/**
	 * 判断当前记录是否生效或关闭
	 * @param id
	 * @param para
	 * @return
	 */
	public String getInterface_checkboxpopedom(String id){
		RecordSet rs = new RecordSet();
		List<String> resultList = new ArrayList<String>();
		rs.executeQuery("select interfaceType from fnainvoiceinterface where id =?",id);
		int interfaceType=-1;
		if(rs.next()){
			interfaceType = Util.getIntValue(rs.getString("interfaceType"),0);
		}
		if(interfaceType==2){
			return "false";
		}else{
			return "true";
		}

	}

	/**
	 * 判断已处理，未处理
	 * @param id
	 * @param para
	 * @return
	 */
	public List<String> getHandleStatus_popedom(String id,String para){
		RecordSet rs = new RecordSet();
		List<String> resultList = new ArrayList<String>();
		String sql = "select handleStatus from FnaInvoiceCheckFailLog where id = "+id;
		rs.execute(sql);
		int handleStatus = 0;
		if(rs.next()){
			handleStatus = Util.getIntValue(rs.getString("handleStatus"),0);
		}
		if(handleStatus == 0){
			resultList.add("true");
			resultList.add("false");
		}else{
			resultList.add("false");
			resultList.add("true");
		}
		return resultList;
	}

	/**
	 * 赋值发票信息（包括主表，明细表）
	 * @param checkIds
	 * @return
	 */
	public void getFnaInvoiceLedgerList(String checkIds,FnaAbstractInterface fnaAbstractInterface){
		RecordSet rs = new RecordSet();
		RecordSet rs2 = new RecordSet();
		ArrayList<FnaInvoiceLedger> arrayList = new ArrayList<FnaInvoiceLedger>();
		Map<String, List<FnaInvoiceLedgerDetail>> detailMap = new HashMap<String, List<FnaInvoiceLedgerDetail>>();
		rs.execute("select * from FnaInvoiceLedger where id in ( "+checkIds+" 0 )");
		while(rs.next()){
			//查询发票主表信息
			String invoiceNumber= Util.null2String(rs.getString("InvoiceNumber"));
			int id = Util.getIntValue(rs.getString("id"));
			FnaInvoiceLedger fnaInvoiceLedger = new FnaInvoiceLedger();
			fnaInvoiceLedger.setId(id);
			fnaInvoiceLedger.setBillingDate(Util.null2String(rs.getString("BillingDate")));
			fnaInvoiceLedger.setInvoiceCode(Util.null2String(rs.getString("InvoiceCode")));
			fnaInvoiceLedger.setInvoiceNumber(invoiceNumber);
			fnaInvoiceLedger.setInvoiceType(Util.getIntValue(rs.getString("InvoiceType")));
			fnaInvoiceLedger.setSeller(Util.null2String(rs.getString("Seller")));
			fnaInvoiceLedger.setPurchaser(Util.null2String(rs.getString("Purchaser")));
			fnaInvoiceLedger.setInvoiceServiceYype(Util.null2String(rs.getString("InvoiceServiceYype")));
			fnaInvoiceLedger.setPriceWithoutTax(Util.getDoubleValue(rs.getString("PriceWithoutTax")));
			fnaInvoiceLedger.setTaxRate(Util.getDoubleValue(rs.getString("TaxRate")));
			fnaInvoiceLedger.setTax(Util.getDoubleValue(rs.getString("Tax")));
			fnaInvoiceLedger.setTaxIncludedPrice(Util.getDoubleValue(rs.getString("TaxIncludedPrice")));
			fnaInvoiceLedger.setAuthenticity(Util.getIntValue(rs.getString("Authenticity")));
			fnaInvoiceLedger.setCheckStatus(Util.getIntValue(rs.getString("checkStatus")));
			fnaInvoiceLedger.setCheckCode(Util.null2String(rs.getString("CheckCode")));
			arrayList.add(fnaInvoiceLedger);
			//查询明细表信息
			rs2.execute("select * from FnaInvoiceLedgerDetail where mainid = "+id);
			List<FnaInvoiceLedgerDetail> detailList = new ArrayList<FnaInvoiceLedgerDetail>();
			while(rs2.next()){
				FnaInvoiceLedgerDetail fnaInvoiceLedgerDetail = new FnaInvoiceLedgerDetail();
				fnaInvoiceLedgerDetail.setInvoiceServiceYype(Util.null2String(rs2.getString("invoiceServiceYype")));
				fnaInvoiceLedgerDetail.setPriceWithoutTax(Util.getDoubleValue(rs2.getString("priceWithoutTax")));
				fnaInvoiceLedgerDetail.setTaxRate(Util.getDoubleValue(rs2.getString("taxRate")));
				fnaInvoiceLedgerDetail.setTax(Util.getDoubleValue(rs2.getString("tax")));
				detailList.add(fnaInvoiceLedgerDetail);
			}
			detailMap.put(invoiceNumber, detailList);
		}
		fnaAbstractInterface.setArrayList(arrayList);
		fnaAbstractInterface.setDetailMap(detailMap);
	}




	/**
	 * 流程强制收回，退回，删除等操作时，修改发票状态为未冻结状态
	 * @param requestid
	 */
	public void doWfForceOver(int requestid) {
		doWfForceOver(requestid,"",new User(1));
	}
		/**
		 * 流程强制收回，退回，删除等操作时，修改发票状态为未冻结状态
		 * @param requestid
		 */
	public void doWfForceOver(int requestid,String ipAdress,User user){
        //初始化发票状态
		RecordSet rs = new RecordSet();
		Map<String,List<String>> mapCloud = new HashMap<String,List<String>>();//其中key为userid_new， value为的List
		Map<String,String> mapCloudOA = new HashMap<String,String>();//其中key为invoiceId， value为的cloudId
		//添加日志
		FnaLogSqlUtil fnaLogSqlUtil = new FnaLogSqlUtil();
		Map<String, Map<String, String>> labelIdMaps = new HashMap<String, Map<String, String>>();
		Map<String, Map<String, String>> beforeMaps = new HashMap<String, Map<String, String>>();


		StringBuffer sqlBuffer = new StringBuffer();
		rs.executeQuery("select * from fnainvoiceledger where requestid =?",requestid);
		while(rs.next()){
			String invoiceId = Util.null2String(rs.getString("id"));
			String cloudId = Util.null2String(rs.getString("cloudId"));
			String userid_new = Util.null2String(rs.getString("userId_new"));

			if(mapCloud.containsKey(userid_new)){
				List<String> cloudIdList = mapCloud.get(userid_new);
				if(!cloudIdList.contains(cloudId)){
					cloudIdList.add(cloudId);
					mapCloud.put(userid_new,cloudIdList);
				}
			}else{
				List<String> cloudIdList = new ArrayList<>();
				cloudIdList.add(cloudId);
				mapCloud.put(userid_new,cloudIdList);
			}
			mapCloudOA.put(invoiceId,cloudId);
			//添加至日志map
			fnaLogSqlUtil.getActionInvoiceLogInfo(invoiceId,labelIdMaps,beforeMaps);
			if(sqlBuffer.length() > 0){
				sqlBuffer.append(",");
			}
			sqlBuffer.append(invoiceId);
		}
		int workflowlogic = ReimbursementUtil.getWorkflowlogic();
        StringBuffer invoiceIdBuffer = new StringBuffer();
        if(workflowlogic==3) {
            rs.executeQuery("select b.id,b.cloudId,b.userId_new from FnaInvoiceReimbursement a join fnainvoiceledger b on a.mainid=b.id where a.requestid = ?",requestid);
            while (rs.next()){
                String invoiceId = Util.null2String(rs.getString("id"));
                String cloudId = Util.null2String(rs.getString("cloudId"));
                String userid_new = Util.null2String(rs.getString("userId_new"));

                if(mapCloud.containsKey(userid_new)){
                    List<String> cloudIdList = mapCloud.get(userid_new);
                    if(!cloudIdList.contains(cloudId)){
                        cloudIdList.add(cloudId);
                        mapCloud.put(userid_new,cloudIdList);
                    }
                }else{
                    List<String> cloudIdList = new ArrayList<>();
                    cloudIdList.add(cloudId);
                    mapCloud.put(userid_new,cloudIdList);
                }
                mapCloudOA.put(invoiceId,cloudId);
                fnaLogSqlUtil.getActionInvoiceLogInfo(invoiceId,labelIdMaps,beforeMaps);
                if(invoiceIdBuffer.length()==0){
                    invoiceIdBuffer.append(invoiceId);
                }else{
                    invoiceIdBuffer.append(",").append(invoiceId);
                }
            }
        }

		//发票云报销修改发票云数据
		RecordSet rs5= new RecordSet();
		for(Map.Entry<String,List<String>> entry : mapCloud.entrySet()){
			String userid_new = entry.getKey();
			List<String> cloudIdList = entry.getValue();//发票id
			int userid_newInt = Util.getIntValue(Util.null2String(userid_new),0);
			JSONObject interfaceInfo = InvoiceCloudUtil.getInterfaceInfo(new User(userid_newInt), false, false, true);
			JSONObject cloudInfo = interfaceInfo.getJSONObject("cloud");
			boolean existEffectCloud = cloudInfo.getBoolean("existEffectCloud");
			if(existEffectCloud){
				String cid = Util.null2String(cloudInfo.getString("cid"));
				String userName = Util.null2String(cloudInfo.getString("userName"));
				String password = Util.null2String(cloudInfo.getString("password"));
				String aesKey = Util.null2String(cloudInfo.getString("aesKey"));
				String reimburseUrl = Util.null2String(cloudInfo.getString("reimburseUrl"));


				JSONObject bodyJson = new JSONObject();
				bodyJson.put("cid",cid);
				bodyJson.put("userId",user.getUID());
				bodyJson.put("flag","2");
				JSONArray fnaInvoiceReimburseInfoJa = new JSONArray();
				if(workflowlogic==3){
					rs5.executeQuery("select * from FnaInvoiceReimbursement where requestid=?",requestid);
					while (rs5.next()){
						String cloudId = mapCloudOA.get(Util.null2String(rs5.getString("mainid")));
						if(cloudIdList.contains(cloudId)) {
							JSONObject fnaInvoiceReimburseInfoJo = new JSONObject();
							fnaInvoiceReimburseInfoJo.put("dataid", requestid);
							fnaInvoiceReimburseInfoJo.put("amount", "");
							fnaInvoiceReimburseInfoJo.put("uid", "");
							fnaInvoiceReimburseInfoJo.put("date", "");
							fnaInvoiceReimburseInfoJo.put("name", "");
							fnaInvoiceReimburseInfoJo.put("fid", cloudId);
							fnaInvoiceReimburseInfoJo.put("cid", cid);
							fnaInvoiceReimburseInfoJa.add(fnaInvoiceReimburseInfoJo);
						}
					}
				}else{
					rs5.executeQuery("select * from fnaInvoiceLedger where requestid=?",requestid);
					while (rs5.next()){
						String cloudId = Util.null2String(rs5.getString("cloudId"));
						if(cloudIdList.contains(cloudId)) {
							JSONObject fnaInvoiceReimburseInfoJo = new JSONObject();
							fnaInvoiceReimburseInfoJo.put("dataid", requestid);
							fnaInvoiceReimburseInfoJo.put("amount", "");
							fnaInvoiceReimburseInfoJo.put("uid", "");
							fnaInvoiceReimburseInfoJo.put("date", "");
							fnaInvoiceReimburseInfoJo.put("name", "");
							fnaInvoiceReimburseInfoJo.put("fid", cloudId);
							fnaInvoiceReimburseInfoJo.put("cid", cid);
							fnaInvoiceReimburseInfoJa.add(fnaInvoiceReimburseInfoJo);
						}
					}
				}
				bodyJson.put("infos",fnaInvoiceReimburseInfoJa);
				bodyJson.put("sreim","0");
				try {
					JSONObject reimburseJson = InvoiceCloudUtil.reimburseInvoice(reimburseUrl, aesKey, bodyJson, userName, password, "解锁报销修改数据");
					if(!reimburseJson.getBoolean("flag")){
						throw new Exception(reimburseJson.getString("msg"));
					}
				}catch (Exception e){
					new BaseBean().writeLog("解锁报销修改数据错误："+e.getMessage());
				}
			}
		}


		if(sqlBuffer.length()>0){
			String updateInvoceStatus = "update fnainvoiceledger set status = "+FnaInvoiceCommon.INIT_STATUS+",reimbursementDate=NULL,requestid=NULL,reimbursePerson=NULL "+
					" where id in ("+sqlBuffer.toString()+")";
			rs.executeUpdate(updateInvoceStatus);
		}
		//去重校验控制逻辑
		if(workflowlogic==3) {
			if(invoiceIdBuffer.length()>0){
				FnaInvoiceCommon.executeInSql("update fnainvoiceledger set status = "+FnaInvoiceCommon.INIT_STATUS+",reimbursementDate=NULL,requestid=NULL,reimbursePerson=NULL " +
								" where id in(占位符标识)",invoiceIdBuffer.toString(),"executeUpdate");
			}
			rs.executeUpdate("delete from FnaInvoiceReimbursement where requestid = ?", requestid);
		}


		//更新日志信息
		for (Map.Entry<String, Map<String, String>> entry : labelIdMaps.entrySet()) {
			String invoiceId = entry.getKey();
			Map<String, String> labelIdMap = entry.getValue();
			Map<String, String> beforeMap = beforeMaps.get(invoiceId);
            //插入日志2
			Map<String, String> afterMap =fnaLogSqlUtil.getInvoiceMap(invoiceId,labelIdMap);
			fnaLogSqlUtil.invoiceLedgerAddlog(user,ipAdress,"2",invoiceId,"4",
					beforeMap,afterMap,labelIdMap);
		}




	}

	/**
	 * 获取发票信息入口
	 * @param jsonObject
	 * @param userid
	 * @return
	 */
	public String getInfoEntrance(JSONObject jsonObject,int userid){
		String entryTime = Util.date(2);//录入时间
		DecimalFormat df = new DecimalFormat("#######################0.00");
		RecordSet rs = new RecordSet();
		try{
			JSONArray jsonArray = jsonObject.getJSONArray("info");
			writeLog("jsonArray:", jsonArray);
			Iterator iterator = jsonArray.iterator();
			StringBuffer param = new StringBuffer();
			param.append("{\"item_list\": [");
			int count = 0;
			HashMap<String, String> cardMap = new HashMap<String, String>();
			while(iterator.hasNext()){
				JSONObject json = (JSONObject)iterator.next();
				String card_id = json.getString("card_id");
				String encrypt_code = json.getString("encrypt_code");
				//判断此card_id是否已经在表中存在,已经同步过的不需要同步
				if(judgeCardId(card_id,encrypt_code,rs)){
					continue;
				}
				if(count > 0){
					param.append(",");
				}
				cardMap.put(card_id+"_index"+count, encrypt_code);
				param.append("{\"card_id\":\""+card_id+"\",").append("\"encrypt_code\":\""+encrypt_code+"\"}");
				count ++;
			}
			param.append("]}");
			String token = getAccessToken();
			if("".equals(token)){
				return ""+ SystemEnv.getHtmlLabelName(10003158,weaver.general.ThreadVarLanguage.getLang())+"token"+ SystemEnv.getHtmlLabelName(498,weaver.general.ThreadVarLanguage.getLang())+"!";
			}
			writeLog("token:", token);
			writeLog("param:", param);
			JSONObject invoiceInfoJson = getElecInvoiceInfoBatch(param.toString(), token);
			writeLog("invoiceInfoJson:", invoiceInfoJson);
			String errorMsg = Util.null2String(invoiceInfoJson.get("errorMsg"));
			//判断调用方法时是否存在错误
			if(!"".equals(errorMsg)){
				return invoiceInfoJson.getString("errorMsg");
			}
			//判断返回结果是否错误
			String errcode = invoiceInfoJson.getString("errcode");
			if(!"0".equals(errcode)){
				String errmsg = invoiceInfoJson.getString("errmsg");
				return CONCURRENT_HASH_MAP.containsKey(errcode) ? CONCURRENT_HASH_MAP.get(errcode):errmsg;
			}
			JSONArray jsonArrayItem_list = invoiceInfoJson.getJSONArray("item_list");
			Iterator iteratorItem_list = jsonArrayItem_list.iterator();
			count = 0;
			while(iteratorItem_list.hasNext()){
				JSONObject json = (JSONObject)iteratorItem_list.next();
				String card_id = json.getString("card_id");
				String openid = json.getString("openid");
				String encrypt_code = cardMap.get(card_id+"_index"+count);
				String seller = json.getString("payee");//销售方
				JSONObject user_info = json.getJSONObject("user_info");
				String billingDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date(user_info.getLong("billing_time")*1000));//开票日期
				String invoiceNumber = user_info.getString("billing_code");//发票号码
				String invoiceCode = user_info.getString("billing_no");//发票代码
				String purchaser = user_info.getString("title");//购买方
				String checkcode = user_info.getString("check_code");//校验码

				//这两个字段不一定在json中存在
				String priceWithoutTax = "0.00";//金额（不含税价）
				if(user_info.containsKey("fee_without_tax")){
					priceWithoutTax = df.format(Double.parseDouble(user_info.getString("fee_without_tax"))/100);
				}
				String tax = "0.00";//税额（税价）
				if(user_info.containsKey("tax")){
					tax = df.format(Double.parseDouble(user_info.getString("tax"))/100);
				}

				String taxIncludedPrice = df.format(Double.parseDouble(user_info.getString("fee"))/100);//价税合计

				String taxRate = "0.00";//税率
				if(!"0.00".equals(priceWithoutTax)){
					taxRate = getRoundNumber((Double.parseDouble(tax) / Double.parseDouble(priceWithoutTax)) * 100);
				}

				@SuppressWarnings("unused")
				String pdf_url = user_info.getString("pdf_url");//这张发票对应的PDF_URL

//				new BaseBean().writeLog("pdf_url:", pdf_url);

				/**
				 * INVOICE_REIMBURSE_INIT 发票初始状态，未锁定，可提交报销
				 * INVOICE_REIMBURSE_LOCK 发票已锁定，无法重复提交报销
				 * INVOICE_REIMBURSE_CLOSURE 发票已核销，从用户卡包中移除
				 */
				String reimburse_status = user_info.getString("reimburse_status");//发票报销状态

				//只有未冻结的发票才能被选到，默认为0
				int status = INIT_STATUS;

				String invoiceServiceYype = "";//货物或应税服务类型
				JSONArray infoArray = user_info.getJSONArray("info");
				for(int arr=0;arr<infoArray.size();arr++){
					if(infoArray.getJSONObject(arr).containsKey("name")){
						invoiceServiceYype = infoArray.getJSONObject(arr).getString("name");
					}else{
						invoiceServiceYype = ""+ SystemEnv.getHtmlLabelName(10003274,weaver.general.ThreadVarLanguage.getLang())+"";
					}
				}

				int invoiceType = 15;

				//invoiceSource发票来源 1.微信同步 2.国信扫描

				//判断此发票是否已经通过国信扫描插入了发票表中,为插入则通过微信插入数据
				//微信返回信息不完整，不导入明细信息
				//默认有效未查验
				if(!this.ifExist(invoiceNumber,invoiceCode, rs)){
					String insertInvoice = " insert into fnaInvoiceLedger "+ //1
							" (billingDate,invoiceCode,invoiceNumber,"+//2
							" invoiceType,seller,purchaser,"+//3
							" invoiceServiceYype,priceWithoutTax,taxRate,tax,taxIncludedPrice,authenticity,checkStatus,checkcode,userId_new,"+//4
							" card_id_new,encrypt_code_new,status,invoiceSource_new,"+//5
							" openid_new,wechatstatus,entryTime)"+//6
							" VALUES ('"+StringEscapeUtils.escapeSql(billingDate)+"','"+StringEscapeUtils.escapeSql(invoiceCode)+"','"+StringEscapeUtils.escapeSql(invoiceNumber)+"',"+//1
							" "+invoiceType+",'"+StringEscapeUtils.escapeSql(seller)+"','"+StringEscapeUtils.escapeSql(purchaser)+"',"+//2
							" '"+StringEscapeUtils.escapeSql(invoiceServiceYype)+"',"+priceWithoutTax+","+taxRate+","+tax+","+taxIncludedPrice+",1,2,'"+StringEscapeUtils.escapeSql(checkcode)+"',"+userid+","+//3
							" '"+StringEscapeUtils.escapeSql(card_id)+"','"+StringEscapeUtils.escapeSql(encrypt_code)+"','"+status+"',"+INVOICESOURCE_WECHAT+//4
							",'"+StringEscapeUtils.escapeSql(openid)+"','"+StringEscapeUtils.escapeSql(reimburse_status)+"','"+entryTime+"'"+//5
							" )";//6
					rs.execute(insertInvoice);


					//插入日志
					FnaLogSqlUtil fnaLogSqlUtil  = new FnaLogSqlUtil();
					Map<String, String> labelIdMap = new HashMap<String, String>();
					Map<String, String> beforeMap = new HashMap<String, String>();
					int invoiceId = InvoiceUtil.getInvoiceId(invoiceNumber,invoiceCode);
					Map<String, String> afterMap =fnaLogSqlUtil.getInvoiceMap(String.valueOf(invoiceId),labelIdMap);
					fnaLogSqlUtil.invoiceLedgerAddlog(new User(userid),"","0",String.valueOf(invoiceId),"0",
							beforeMap,afterMap,labelIdMap);
				}
				count++;
			}

		}catch(Exception e){
			return e.getMessage();
		}
		return "";
	}

	/**
	 * 更新发票状态
	 * @param invoiceAmtMap
	 * @param requestid
	 * @param userid 流程创建人
	 * @param doubleCheckInvoiceList
	 * @param type
	 * @param user  当前人员
	 * @param ipAdress
	 * @throws Exception
	 */
	public void changeStatusEntrance(Map<String,Double> invoiceAmtMap,String requestid,int userid,ArrayList<String> doubleCheckInvoiceList,String type,User user,String ipAdress) throws Exception{
		RecordSet rs = new RecordSet();
		try {


			for(Map.Entry<String, Double> entry : invoiceAmtMap.entrySet()) {
				String invoiceId = entry.getKey();

				double canReimbursementAmt = ReimbursementUtil.getCanReimbursementAmt(invoiceId);
				//选择了一张发票的情况下
				if(doubleCheckInvoiceList.contains(invoiceId)){
					double reimbursementAmt = entry.getValue();
					String updateInvoceStatus = "";
					if(reimbursementAmt < canReimbursementAmt) {
						updateInvoceStatus = "update fnainvoiceledger set status = "+FnaInvoiceCommon.INIT_STATUS+",reimbursementDate=NULL,requestid=NULL,reimbursePerson=NULL "+
								" where id = ? ";
					}else if(reimbursementAmt == canReimbursementAmt){
						if("lock".equals(type)){
							updateInvoceStatus = "update fnainvoiceledger set status = "+FnaInvoiceCommon.LOCK_STATUS+",reimbursementDate=NULL,requestid=NULL,reimbursePerson=NULL "+
									" where id = ? ";
						}else{
							updateInvoceStatus = "update fnainvoiceledger set status = "+FnaInvoiceCommon.CLOSURE_STATUS+",reimbursementDate=NULL,requestid=NULL,reimbursePerson=NULL "+
									" where id = ? ";
						}
					}
					rs.executeUpdate(updateInvoceStatus,invoiceId);
					rs.executeUpdate("insert into FnaInvoiceReimbursement(mainid,requestid,reimbursementAmt,reimbursementDate,userid) values (?,?,?,?,?)",
							invoiceId,requestid,reimbursementAmt,new SimpleDateFormat("yyyy-MM-dd").format(new Date()),userid);
				}else{//选择多张发票的情况下，全额报销
					String updateInvoceStatus = "";
					if("lock".equals(type)){
						updateInvoceStatus = "update fnainvoiceledger set status = "+FnaInvoiceCommon.LOCK_STATUS+",reimbursementDate=NULL,requestid=NULL,reimbursePerson=NULL "+
								" where id = ? ";
					}else{
						updateInvoceStatus = "update fnainvoiceledger set status = "+FnaInvoiceCommon.CLOSURE_STATUS+",reimbursementDate=NULL,requestid=NULL,reimbursePerson=NULL "+
								" where id = ? ";
					}
					rs.executeUpdate(updateInvoceStatus,invoiceId);
					rs.executeUpdate("insert into FnaInvoiceReimbursement(mainid,requestid,reimbursementAmt,reimbursementDate,userid) values (?,?,?,?,?)",
							invoiceId,requestid,canReimbursementAmt,new SimpleDateFormat("yyyy-MM-dd").format(new Date()),userid);
				}
			}


		} catch (Exception e) {
			throw new Exception(e.getMessage());
		}
	}

	/**
	 * 获取验票接口
	 * @param user
	 * @throws Exception
	 */
	/*public FnaAbstractInterface getInterface(User user) throws Exception{
		int baiwangtype = Util.getIntValue(getPropValue("baiwang", "type"),0);
		FnaInvoiceCommon.getinterface();
		String Type = FnaInvoiceInterface.getInstance().getType();
		FnaAbstractInterface fnaAbstractInterface = null;
		if("1".equals(Type)){//国信接口
			fnaAbstractInterface = new FnaBaiwangOpenApi(user);
		}else if("2".equals(Type)){//百望接口
			if(baiwangtype == 0){
				fnaAbstractInterface = new FnaBaiwangOpenApi(user);
			}else {
				fnaAbstractInterface = new FnaBaiwangOpenApi(user);
			}
		}else{
			throw new Exception(SystemEnv.getHtmlLabelName(520790,user.getLanguage()));//后台【预算】-【发票管理】-【发票接口配置】未配置生效的增值税发票查验接口！
		}
		fnaAbstractInterface.setUser(user);
		return fnaAbstractInterface;
	}*/

	/**
	 * 获取验票接口
	 * @param user
	 * @throws Exception
	 */
	public FnaAbstractInterface getInterface(User user) throws Exception{
		FnaAbstractInterface fnaAbstractInterface = new FnaBaiwangOpenApi(user);
		fnaAbstractInterface.setUser(user);
		return fnaAbstractInterface;
	}


	/**
	 * 获取发票参数
	 * @param invoiceId
	 * @param rs
	 * @return
	 */
	public String[] getInvoiceInfoParam(String invoiceId,RecordSet rs){
		String[] params = new String[4];
		String sql = "select invoiceSource_new,card_id_new,encrypt_code_new,openid_new from FnaInvoiceLedger where id="+invoiceId;
		rs.execute(sql);
		String invoiceSource = "";
		String card_id = "";
		String encrypt_code = "";
		String openid_new = "";
		while(rs.next()){
			invoiceSource = Util.null2String(rs.getString("invoiceSource_new"));
			card_id = Util.null2String(rs.getString("card_id_new"));
			encrypt_code = Util.null2String(rs.getString("encrypt_code_new"));
			openid_new = Util.null2String(rs.getString("openid_new"));
		}
		params[0] = invoiceSource;
		params[1] = card_id;
		params[2] = encrypt_code;
		params[3] = openid_new;
		return params;
	}

	/**
	 * 查询电子发票信息
	 * @param param
	 * @return
	 */
	public JSONObject getElecInvoiceInfoBatch(String param,String token){
		String httpUrl = GETINVOICEINFOBATCH_URL + token;
		return httpRequest(httpUrl,param);
	}

	/**
	 * 更新发票状态
	 * @param param
	 * @param token
	 * @return
	 */
	public JSONObject updateElecInvoiceStatus(String param,String token){
		String httpUrl = UPDATEINVOICESTATUS_URL + token;
		return httpRequest(httpUrl,param);
	}

	/**
	 * 调用微信接口通用方法
	 * @param requestUrl
	 * @param param
	 * @return
	 */
	@SuppressWarnings(value={"resource"})
	public JSONObject httpRequest(String requestUrl,String param){
		JSONObject jsonObject = new JSONObject();
		HttpClient httpClient = new DefaultHttpClient();
	    HttpPost post = new HttpPost(requestUrl);
	    try {
	    	if(param != null){
		    	StringEntity postingString = new StringEntity(param);
			    post.setEntity(postingString);
			    post.setHeader("Content-type", "application/json");
	    	}
		    HttpResponse response = httpClient.execute(post);
		    String content = EntityUtils.toString(response.getEntity());
		    jsonObject = JSONObject.fromObject(content);
		} catch (Exception e) {
			jsonObject.put("errorMsg", e.getMessage());
		}
	    return jsonObject;
	}

	/**
	 * 四舍五入
	 * @param number
	 * @return
	 */
	public String getRoundNumber(double number){
		DecimalFormat df = new DecimalFormat("################################0.00");
		if(number == 0){
			return "0.00";
		}
		return df.format(((double)Math.round(number)));
	}

	/**
	 * 获取token
	 * @return
	 */
	public String getAccessToken() throws Exception{
		Map<String,String> params = new HashMap<String, String>();
		params.put("corpId", corpId);
		String appStr = APPManager.getThirdAccessToken(params);
		new BaseBean().writeLog("appStr:", appStr);
		JSONObject jsonObject = JSONObject.fromObject(appStr);
		String errcode = Util.null2String(jsonObject.get("errcode"));
		String access_token = "";
		if("0".equals(errcode)){
			access_token = jsonObject.getString("accessToken");
		}else{
			throw new Exception(jsonObject.getString("errmsg"));
		}
		new BaseBean().writeLog("access_token:", access_token);
		return access_token;
	}

	/**
	 * 删除电子发票
	 * @param card_id
	 * @param rs
	 */
	public void deleteCardId(String card_id,RecordSet rs){
		String sql = "delete from FnaInvoiceLedger where card_id='"+StringEscapeUtils.escapeSql(card_id)+"'";
		rs.execute(sql);
	}

	/**
	 * 判断card_id是否存在
	 * @param card_id
	 * @param encrypt_code
	 * @param rs
	 * @return
	 */
	public boolean judgeCardId(String card_id,String encrypt_code,RecordSet rs){
		String sql = "select 1 from fnaInvoiceLedger where card_id_new = '"+StringEscapeUtils.escapeSql(card_id)+"' and encrypt_code_new = '"+StringEscapeUtils.escapeSql(encrypt_code)+"' ";
		rs.execute(sql);
		if(rs.next()){
			return true;
		}
		return false;
	}


	/**
	 * 判断扫描的发票是否在表中已经存在（发票号码），之前很多方法不用了，为保证不报错，选择重载
	 * @param invoiceNumber
	 * @param rs
	 * @return
	 */
	public boolean ifExist(String invoiceNumber,RecordSet rs){
		String sql = "select 1 from fnaInvoiceLedger where invoiceNumber = '"+StringEscapeUtils.escapeSql(invoiceNumber)+"'";
		rs.execute(sql);
		if(rs.next()){
			return true;
		}
		return false;
	}


	/**
	 * 判断扫描的发票是否在表中已经存在（发票代码和发票号码）
	 * @param invoiceNumber
	 * @param rs
	 * @return
	 */
	public boolean ifExist(String invoiceNumber,String invoiceCode, RecordSet rs){
		String sql = "select 1 from fnaInvoiceLedger where invoiceNumber = ? and invoiceCode = ? ";
		rs.executeQuery(sql, invoiceNumber,invoiceCode);
		if(rs.next()){
			return true;
		}
		return false;
	}

	/**
	 * 判断扫描的发票是否在表中已经存在（发票代码和发票号码）,并且发票为有效已查验、有效未查验
	 * @param invoiceNumber
	 * @param rs
	 * @return
	 */
	public boolean ifExistAuthenticity(String invoiceNumber,String invoiceCode, RecordSet rs){
		String sql = "select 1 from fnaInvoiceLedger where invoiceNumber = ? and invoiceCode = ?  and (checkStatus =1 or checkStatus=2) ";
		rs.executeQuery(sql, invoiceNumber,invoiceCode);
		if(rs.next()){
			return true;
		}
		return false;
	}

	/**
	 * 判断扫描的发票是否在表中已经存在（发票代码和发票号码）,并且发票为有效已查验
	 * @param invoiceNumber
	 * @param rs
	 * @return
	 */
	public boolean ifExistAuthenticity2(String invoiceNumber,String invoiceCode, RecordSet rs){
		String sql = "select 1 from fnaInvoiceLedger where invoiceNumber = ? and invoiceCode = ?  and checkStatus =1";
		rs.executeQuery(sql, invoiceNumber,invoiceCode);
		if(rs.next()){
			return true;
		}
		return false;
	}


	/**
	 * 获取配置的自动验票地址
	 * @return
	 */
	public static void getinterface(){
		RecordSet rs = new RecordSet();
		rs.execute("select * from fnainvoiceinterface where (type = 1 or (type = 2 and interfaceType = 1)) and status = 1");
		if(rs.next()){
			String type = Util.null2String(rs.getString("type"));
			String interfaceurl = Util.null2String(rs.getString("interfaceurl"));
			String userName = Util.null2String(rs.getString("userName"));
			String password = Util.null2String(rs.getString("password"));
			FnaInvoiceInterface.getInstance().setType(type);
			FnaInvoiceInterface.getInstance().setInterfaceurl(interfaceurl);
			FnaInvoiceInterface.getInstance().setUserName(userName);
			FnaInvoiceInterface.getInstance().setPassword(password);
		}else{
			FnaInvoiceInterface.getInstance().setType("");
			FnaInvoiceInterface.getInstance().setInterfaceurl("");
			FnaInvoiceInterface.getInstance().setUserName("");
			FnaInvoiceInterface.getInstance().setPassword("");
		}
	}

	/**
	 * 压缩上传的图片,图片的大小大于2.5M时，进行图片压缩
	 * @param imageBytes
	 * @return
	 */
	public byte[] compressImage(byte[] imageBytes){
		ByteArrayInputStream byteArrayInputStream = null;
		ByteArrayOutputStream byteArrayOutputStream = null;
		try {
			double quality = 1d;
			while(quality >= 0){
				byteArrayInputStream = new ByteArrayInputStream(imageBytes);
				byteArrayOutputStream = new ByteArrayOutputStream();
				//压缩图片
				Thumbnails.of(byteArrayInputStream).scale(1).outputQuality(quality).toOutputStream(byteArrayOutputStream);
				if(byteArrayOutputStream.toByteArray().length <= MAX_BYTES){
					break;
				}
				//压缩之后图片还是大于2.5M，继续压缩
				quality = quality - DIMINISHING_INTERVAL;
			}
			writeLog("压缩质量：",quality);
		} catch (Exception e) {
			writeLog("压缩出现错误：", e.getMessage());
		} finally {
			try {
				if(byteArrayInputStream!=null) byteArrayInputStream.close();
				if(byteArrayOutputStream!=null) byteArrayOutputStream.close();
			} catch (Exception e) {
				writeLog("出现错误：", e.getMessage());
			}
		}
		return byteArrayOutputStream.toByteArray();
	}

	/**
	 * 获取发票图片
	 * @param imageID
	 * @param canEditAll
	 * @param userid
	 * @return
	 */
	public String getImageBase64(int imageID,boolean canEditAll,int userid){
		if(imageID>0){
			RecordSet rs = new RecordSet();
			rs.executeQuery("select id from FnaInvoiceLedger where imageID = ?", imageID);
			int invoiceId = 0;
			if(rs.next()){
				invoiceId = Util.getIntValue(rs.getString("id"));
			}
			if(getInvoicePermission(invoiceId, canEditAll, userid)){
				return changeFileTobase64(ImageFileManager.getInputStreamById(imageID));
			}
		}
		return "-1";
	}

	/**
	 * 查看发票权限
	 * @param invoiceId
	 * @param canEditAll
	 * @param userid
	 * @return
	 */
	public boolean getInvoicePermission(int invoiceId,boolean canEditAll,int userid){
		boolean canView = false;
		if(invoiceId>0){
			canView = canEditAll;
			if(!canView){
				RecordSet rs = new RecordSet();
				rs.executeQuery("select 1 from fnaInvoiceLedger where (userid_new = ? or id in ( select invoiceId from fnaInvoiceSharer where sharer = ? )) and id = ?", userid, userid, invoiceId);
				if(rs.next()){
					canView = true;
				}else{
					String sql=" select count(*) cnt " +
							" from workflow_currentoperator a " +
							" join FnaInvoiceLedger b on a.requestid = b.requestid " +
							"  where b.id =? and a.userid in(";

					//通过userid查询该userid关联的所有主从账号id
					List<String> sqlList = new ArrayList<String>();
					sqlList.add(String.valueOf(invoiceId));
					List<String> useridList = getAllUserid(String.valueOf(userid));
					for(int i=0;i<useridList.size();i++){
						if(i==0){
							sql = sql +"?";
						}else{
							sql = sql +",?";
						}
						sqlList.add(useridList.get(i));
					}
					sql = sql+")";

					rs.executeQuery(sql,sqlList);
					if(rs.next() && rs.getInt("cnt") > 0){
						canView = true;
					}
					if(!canView){
						//去重校验控制逻辑
						int workflowlogic = ReimbursementUtil.getWorkflowlogic();
						if(workflowlogic==3) {
							sql=" select count(*) cnt "+
									" from workflow_currentoperator a "+
									" join FnaInvoiceReimbursement b on a.requestid = b.requestid "+
									" where b.mainid = ? and a.userid in(";
							//通过userid查询该userid关联的所有主从账号id
							sqlList.clear();
							sqlList.add(String.valueOf(invoiceId));
							for(int i=0;i<useridList.size();i++){
								if(i==0){
									sql = sql +"?";
								}else{
									sql = sql +",?";
								}
								sqlList.add(useridList.get(i));
							}
							sql = sql+")";
							rs.executeQuery(sql,sqlList);
							if(rs.next() && rs.getInt("cnt") > 0){
								canView = true;
							}
						}
					}
				}
			}
		}
		return canView;
	}


	/**
	 * 通过一个账号获取管理的所有的主从账号
	 * @param userid
	 * @return
	 */
	public List<String> getAllUserid(String userid){
		List<String> list = new ArrayList<String>();
		try{
			ResourceComInfo resourceComInfo = new ResourceComInfo();
			ResourceBelongtoComInfo resourceBelongtoComInfo = new ResourceBelongtoComInfo();
			String accountType = resourceComInfo.getAccountType(userid);
			if("0".equals(accountType) || "".equals(accountType)){//主账号
				List<User> userList = resourceBelongtoComInfo.getBelongtousers(userid);//获取所有次账号
				for(int i=0;i<userList.size();i++){
					User user = userList.get(i);
					list.add(String.valueOf(user.getUID()));
				}
			}
			if(!list.contains(userid)){
				list.add(userid);
			}
		}catch (Exception e){
			list.add(userid);
		}
		return list;
	}
	/**
	 * 获取发票图片
	 * @param inputStream
	 * @return
	 */
	private String changeFileTobase64(InputStream inputStream){
		ByteArrayOutputStream outStream = new ByteArrayOutputStream();
		byte[] fileByte=null;
		String base64String = "";

		try {
			if(null==inputStream){
				return base64String;
			}
			byte[] buffer = new byte[1024*1000];
			int len = -1;
			while((len=inputStream.read(buffer))!=-1){
				outStream.write(buffer,0,len);
			}
			fileByte = outStream.toByteArray();
			inputStream.read(fileByte);
			inputStream.close();
		} catch (Exception e) {
			new BaseBean().writeLog("changeFileTobase64_Exception:"+e.getMessage());
		}
		if(null!=fileByte){
			base64String = Base64.encodeBase64String(fileByte);
		}
		return base64String;
	}

	/**
	 * 调用接口保存
	 * @param interfaceType
	 * @param infObject
	 * @param user
	 * @param ocrtype
	 */
	public static void addFnainvoiceLog(String interfaceType,byte[] bytes,String invoiceNumber,String invoiceCode,String billingDate,String checkCode,String priceWithoutTax,
										JSONObject infObject,User user,String ocrtype,String appKey){
		RecordSet rs = new RecordSet();
		String posttime = Util.date(2);
		String status = infObject.getString("status");
		if("OCR".equals(ocrtype)){
			interfaceType = ""+ SystemEnv.getHtmlLabelName(521512,weaver.general.ThreadVarLanguage.getLang())+"";
			status = "0".equals(status)?"成功":"失败";
		}else{
			interfaceType = ""+ SystemEnv.getHtmlLabelName(384751,weaver.general.ThreadVarLanguage.getLang())+"";
			status = "1".equals(status)?"成功":"失败";
		}
		int userid = user.getUID();
		String errMsg = "";
		if(infObject.containsKey("errMsg")){
			errMsg = infObject.getString("errMsg");
		}
		String uuid = FnaCommon.getPrimaryKeyGuid1();
		rs.executeUpdate("insert into fnainvoiceLog(interfaceType,posttime,userid,status,msg,ocrtype,accountNumber," +
				"invoiceNumber,invoiceCode,billingDate,checkCode,priceWithoutTax,uuid" +
				") values(?,?,?,?,?,?,?,?,?,?,?,?,?)",interfaceType,posttime,userid,status,errMsg,ocrtype,appKey,invoiceNumber,invoiceCode,billingDate,checkCode,priceWithoutTax,uuid);

		String base64String="";

		if(bytes!=null){//插入ocr bytes数组
			base64String = Base64.encodeBase64String(bytes);
		}

		try {
			FnaCommon.updateDbClobOrTextFieldValue("fnainvoiceLog", "base64String", base64String, "uuid", uuid, "string");
			FnaCommon.updateDbClobOrTextFieldValue("fnainvoiceLog", "interfaceResult", infObject.toString(), "uuid", uuid, "string");
		}catch (Exception e){new BaseBean().writeLog("插入fnainvoiceLog表sql异常");}
		//插入接口返回内容

	}


	/**
	 * 获取MD5
	 * @param s
	 * @return
	 */
	public static String MD5(String s) {
		char hexDigits[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
		try {
			byte[] btInput = s.getBytes();
			// 获得MD5摘要算法的 MessageDigest 对象
			MessageDigest mdInst = MessageDigest.getInstance("MD5");
			// 使用指定的字节更新摘要
			mdInst.update(btInput);
			// 获得密文
			byte[] md = mdInst.digest();
			// 把密文转换成十六进制的字符串形式
			int j = md.length;
			char str[] = new char[j * 2];
			int k = 0;
			for (int i = 0; i < j; i++) {
				byte byte0 = md[i];
				str[k++] = hexDigits[byte0 >>> 4 & 0xf];
				str[k++] = hexDigits[byte0 & 0xf];
			}
			return new String(str);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 补全校验码
	 * @param checkCode
	 * @return
	 */
	@Deprecated
	public String addCheckCode(String checkCode){
		int length = checkCode.length();
		int add = 20 - length;
		StringBuffer addbuffer = new StringBuffer();
		for(int i = 0;i<add;i++){
			addbuffer.append("0");
		}
		return addbuffer.append(checkCode).toString();
	}

	/**
	 * 保存OCR图片
	 * @param imagedata
	 * @return
	 * @throws Exception
	 */
	/*public static int saveImage(byte[] imagedata) throws Exception{
		ImageFileManager imageFileManager=new ImageFileManager();
		String imagefileName = new SimpleDateFormat("yyyyMMdd").format(new Date())+"-"+FnaCommon.getPrimaryKeyGuid1()+".jpg";

		imageFileManager.setImagFileName(imagefileName);
		imageFileManager.setData(imagedata);
		int imageFileId=imageFileManager.saveImageFile();
		return imageFileId;
	}*/


	/**
	 * 保存OCR图片
	 * @param imagedata
	 * @return
	 * @throws Exception
	 */
	public static int saveImage(byte[] imagedata,User user) throws Exception {
		return saveImage(imagedata,user,"jpg");
	}
		/**
		 * 保存OCR图片
		 * @param imagedata
		 * @return
		 * @throws Exception
		 */
	public static int saveImage(byte[] imagedata,User user,String ext) throws Exception{
		synchronized (FnaInvoiceCommon.class) {
			ImageFileManager imageFileManager = new ImageFileManager();
			String imagefileName = new SimpleDateFormat("yyyyMMdd").format(new Date()) + "-" + FnaCommon.getPrimaryKeyGuid1() + "." + ext;

			imageFileManager.setImagFileName(imagefileName);
			imageFileManager.setData(imagedata);
			int imageFileId = imageFileManager.saveImageFile();

			//获取imageCataLog
			int imageCatalog = 0;
			JSONObject interfaceInfo = InvoiceCloudUtil.getInterfaceInfo(user, true, false, true);
			JSONObject cloudInfo = interfaceInfo.getJSONObject("cloud");
			JSONObject ocrInfo = interfaceInfo.getJSONObject("ocr");
			boolean existEffectCloud = cloudInfo.getBoolean("existEffectCloud");
			boolean existEffectOcr = ocrInfo.getBoolean("existEffectOcr");
			if (existEffectCloud) {
				imageCatalog = cloudInfo.getInt("imageCatalog");
			} else if (existEffectOcr) {
				imageCatalog = ocrInfo.getInt("imageCatalog");
			}

			DocSaveService docSaveService = new DocSaveService();
			int imageDocId = docSaveService.accForDoc(imageCatalog, imageFileId, user);


			RecordSet rs = new RecordSet();
			String enterTime = Util.date(2);//录入时间
			rs.executeUpdate("insert into fnaInvoiceImageHistory(imageId,imageDocId,enterTime) values(?,?,?)", imageFileId, imageDocId, enterTime);
			return imageFileId;
		}

	}



	/**
	 * 获取操作人
	 * @param userid
	 * @param para
	 * @return
	 * @throws Exception
	 */
	public String getHrmresourceName(String userid,String para) throws Exception{
		return new ResourceComInfo().getLastname(userid);
	}

	/**
	 * 获取处理情况
	 * @param handleStatus
	 * @param para
	 * @return
	 */
	public String getHandleStatus(String handleStatus,String para){
		if("0".equals(handleStatus)){
			return ""+ SystemEnv.getHtmlLabelName(15746,weaver.general.ThreadVarLanguage.getLang())+"";
		}
		return ""+ SystemEnv.getHtmlLabelName(1454,weaver.general.ThreadVarLanguage.getLang())+"";
	}

	/**
	 * 加密
	 * @param encryptStr
	 * @return
	 */
	public static String fnaEncrypt(String encryptStr){
		SM4Utils sm4Utils = new SM4Utils();
		return sm4Utils.encrypt(encryptStr, SM4);
	}

	/**
	 * 解密
	 * @param decryptStr
	 * @return
	 */
	public static String fnaDecrypt(String decryptStr){
		SM4Utils sm4Utils = new SM4Utils();
		return sm4Utils.decrypt(decryptStr, SM4);
	}
	static final char hexDigits[] = {
			'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
			'A', 'B', 'C', 'D', 'E', 'F'
	};

	/**
	 * 过去刚刚插入的发票的id
	 * @return
	 */
	public int getInvoiceMaxId(){
		//获取发票id
		int id=0;
		RecordSet rs=new RecordSet();
		rs.execute("select max(id) invoiceid from fnaInvoiceLedger");
		if(rs.next()){
			id = Util.getIntValue(rs.getString("invoiceid"));
		}
		return id;
	}

	/**
	 * 已经存在的发票获取发票id，先判断发票是否为当前人员的
	 * @param number 发票号码
	 * @param userid 当前用户的id
	 * @return
	 * @throws Exception
	 */
	public int getInvoiceId(String number,int userid)throws Exception{
		int id=0;
		RecordSet rs=new RecordSet();
		rs.execute("select id from fnaInvoiceLedger where invoiceNumber = '"+number+"' and userid_new = "+userid);
		if(rs.getCounts() == 0){
			throw new Exception("当前发票已经被其他人使用,请勿重复使用！");
		}
		if(rs.next()){
			id = Util.getIntValue(rs.getString("id"));
		}
		return id;
	}


	/**
	 * 判断在FnaCompanyAndTaxpayerNumber表中是否存在type为0的记录，即是否有纳税人识别号维护的记录，接口除外
	 * @return  true 当前系统纳税人识别号需要校验
	 */
	public static boolean isExistInvoiceTaxpayerNumber(){
		RecordSet rs=new RecordSet();
		int count=0;
		rs.executeQuery("select count(id)cnt from FnaCompanyAndTaxpayerNumber where type=0");
		if(rs.next()){
			count= Util.getIntValue(rs.getString("cnt"));
		}
		if(count==0){
			return false;
		}else{
			return true;
		}
	}


	/**
	 * 通过数据库中invoiceSource_new的值，返回发票来源中文名称
	 * @param invoiceSource_new
	 * @return
	 */
	public String getInvoiceSourceNewName(String invoiceSource_new,String language){

		String value="";
		if("1".equals(invoiceSource_new)){//来自微信同步
			value=SystemEnv.getHtmlLabelName(504356,Util.getIntValue(language));
		}else if("3".equals(invoiceSource_new)){//发票台账增加
			value=SystemEnv.getHtmlLabelName(504354,Util.getIntValue(language));
		}else if("4".equals(invoiceSource_new)){//来自接口验票
			value=SystemEnv.getHtmlLabelName(504355,Util.getIntValue(language));
		}else if("5".equals(invoiceSource_new)){//来自OCR识别
			value=SystemEnv.getHtmlLabelName(509429,Util.getIntValue(language));
		}else if("6".equals(invoiceSource_new)){//来自邮件识别
			value=SystemEnv.getHtmlLabelName(515488,Util.getIntValue(language));
		//以下方式来自发票云新增
		}else if("7".equals(invoiceSource_new)){//微信
			value=SystemEnv.getHtmlLabelName(524456,Util.getIntValue(language));
		}else if("8".equals(invoiceSource_new)){//支付宝
			value=SystemEnv.getHtmlLabelName(533074,Util.getIntValue(language));
		}else if("9".equals(invoiceSource_new)){//邮箱
			value=SystemEnv.getHtmlLabelName(518661,Util.getIntValue(language));
		}else if("10".equals(invoiceSource_new)){//拍照
			value=SystemEnv.getHtmlLabelName(128156,Util.getIntValue(language));
		}else if("11".equals(invoiceSource_new)){//扫码
			value=SystemEnv.getHtmlLabelName(533075,Util.getIntValue(language));
		}else if("12".equals(invoiceSource_new)){//手动录入
			value=SystemEnv.getHtmlLabelName(519651,Util.getIntValue(language));
		}else if("13".equals(invoiceSource_new)){//扫码（废弃） 已废弃
			value=SystemEnv.getHtmlLabelName(533076,Util.getIntValue(language));
		}else if("14".equals(invoiceSource_new)){//查验录入
			value=SystemEnv.getHtmlLabelName(533077,Util.getIntValue(language));
		}else if("15".equals(invoiceSource_new)){//企业微信  显示微信
			value=SystemEnv.getHtmlLabelName(524456,Util.getIntValue(language));
		}else if("16".equals(invoiceSource_new)){//公众号    显示微信
			value=SystemEnv.getHtmlLabelName(524456,Util.getIntValue(language));
		}else if("17".equals(invoiceSource_new)){//接口录入
			value=SystemEnv.getHtmlLabelName(533079,Util.getIntValue(language));
		}else if("18".equals(invoiceSource_new)){//文件录入
			value=SystemEnv.getHtmlLabelName(533080,Util.getIntValue(language));
		}else if("19".equals(invoiceSource_new)){//excel导入
			value=SystemEnv.getHtmlLabelName(533081,Util.getIntValue(language));
		}else if("20".equals(invoiceSource_new)){//短信录入
			value=SystemEnv.getHtmlLabelName(533082,Util.getIntValue(language));
		}

		return value;
	}


	/**
	 * 获取发票的查验状态
	 * @param checkStatus  0未查验、1有效已查验、2有效未查验、3无效
	 * @return
	 */
	public String getInvoiceCheckStatus(String checkStatus,String language){

		String value = "";
		if("0".equals(checkStatus)){
			value=SystemEnv.getHtmlLabelName(509610,Util.getIntValue(language));
		}else if("1".equals(checkStatus)){
			value=SystemEnv.getHtmlLabelName(509611,Util.getIntValue(language));
		}else if("2".equals(checkStatus)){
			value=SystemEnv.getHtmlLabelName(509612,Util.getIntValue(language));
		}else if("3".equals(checkStatus)){
			value=SystemEnv.getHtmlLabelName(2245,Util.getIntValue(language));
		}
		return value;
	}

    public String getUpdateOperateInfo (String updateOperate,String language){
		String value = "";
		if("1".equals(updateOperate)){
			value=SystemEnv.getHtmlLabelName(126151,Util.getIntValue(language));
		}else{
			value=SystemEnv.getHtmlLabelName(126152,Util.getIntValue(language));
		}
		return value;
	}

	/**
	 * 保存失败记录
	 * @param userid
	 * @param invoiceType
	 * @param failMsg
	 */
	public static void saveFailLog(int userid,int interfaceType,String failMsg){
		String currentdate = Util.date(2);
		String checkdate = currentdate.substring(0, 10);
		String checktime = currentdate.substring(11);
		RecordSet rs = new RecordSet();
		String interfaceTypeDesc = "";
		if(interfaceType==0){
			interfaceTypeDesc = ""+ SystemEnv.getHtmlLabelName(388612,weaver.general.ThreadVarLanguage.getLang())+"";
		}else{
			interfaceTypeDesc = ""+ SystemEnv.getHtmlLabelName(10003277,weaver.general.ThreadVarLanguage.getLang())+"";
		}
		rs.executeUpdate("insert into FnaInvoiceCheckFailLog(checkdate,checktime,userid,interfaceType,failMsg,handleStatus) values (?,?,?,?,?,?)",
				checkdate,checktime,userid,interfaceTypeDesc,failMsg,0);
	}

	/**
	 * 判断当前纳税人识别号是否维护
	 * @param companyName
	 * @param taxpayerNumber
	 * @return
	 */
	public static boolean protectInvoiceTaxpayerNumber(String companyName,String taxpayerNumber){

		boolean protect = false;
		RecordSet rs=new RecordSet();
		int cnt=getProtectInvoiceTaxpayerNumber();
		if(cnt==0){
			protect = true;
		}else{
			rs.executeQuery("select id  from FnaCompanyAndTaxpayerNumber where companyName=? and taxpayerNumber=? and type = 0", companyName, taxpayerNumber);
			if (rs.next()) {
				protect = true;
			}
		}
		return protect;
	}

	/**
	 * 纳税人识别维护中type=0的数量
	 * @return
	 */

	public static  int getProtectInvoiceTaxpayerNumber(){
		RecordSet rs=new RecordSet();
		int cnt =0;
		rs.executeQuery("select count(id) cnt  from FnaCompanyAndTaxpayerNumber where type=0");
		if(rs.next()){
			cnt = Util.getIntValue(rs.getString("cnt"));
		}
		return cnt;
	}


	/**
	 * 连号发票控制
	 * @param invoiceIds
	 * @param user
	 * @return
	 */
	public JSONObject serialInvoiceControl(String invoiceIds,User user){
		JSONObject serialInvoiceJson = new JSONObject();
        RecordSet rs = new RecordSet();
        try {

			int vatCtrl = 1;//增值税发票是否开启不允许连号报销控制
			int otherCtrl = 1;//其他发票是否开启不允许连号报销控制
			String invoiceTypes = "3,5,6,7,8,9,10,11,12,13,14,17,18,19,22,23";//其他发票的类型
			rs.executeQuery("select * from fnaSerialInvoiceCtrl");
			if (rs.next()) {
				vatCtrl = Util.getIntValue(rs.getString("vatCtrl"),1);
				otherCtrl = Util.getIntValue(rs.getString("otherCtrl"),1);
				invoiceTypes = Util.null2String(rs.getString("invoiceTypes"));
			}
			List<String> invoiceTypeList = Arrays.asList(invoiceTypes.split(","));

			boolean vatExistInWhiltList = false;//增值税连号发票控制当前用户是否已维护于白名单
			boolean otherExistInWhiltList = false;//其他连号发票控制当前用户是否已维护于白名单
			if (vatCtrl==1) {
				vatExistInWhiltList = this.existInWhiltList(user, 1);
			}
			if (otherCtrl==1) {
				otherExistInWhiltList = this.existInWhiltList(user, 2);
			}

			//查询出所有例外的发票
			List<String> exceptInvoiceList = new ArrayList<String>();
			rs.executeQuery("select invoiceId from fnaExceptInvoice");
			while (rs.next()){
				exceptInvoiceList.add(Util.null2String(rs.getString("invoiceId")));
			}
			//查询出需要校验是否连号的发票信息发票号码+发票代码，用

			List<FnaInvoiceLedger> invoiceLedgerList = new ArrayList<FnaInvoiceLedger>();
			if(vatCtrl==1 || otherCtrl==1) {
				rs.executeQuery("select id,invoiceNumber,invoiceCode,invoiceType from fnaInvoiceLedger where id in(" + StringEscapeUtils.escapeSql(invoiceIds) + ")");
				while (rs.next()) {
					String id = Util.null2String(rs.getString("id"));
					String invoiceNumber = Util.null2String(rs.getString("invoiceNumber"));
					String invoiceCode = Util.null2String(rs.getString("invoiceCode"));
					int invoiceType = Util.getIntValue(rs.getString("invoiceType"));
					//如果开启了增值税发票连号控制，并且当前发票是增值税发票
                    if(vatCtrl==1 && (invoiceType==1 || invoiceType==2 || invoiceType==15 || invoiceType==16 || invoiceType==20 || invoiceType==21)){
						//如果当前人员不在把增值税发票连号控制白名单内,并且当前发票不在例外列表中
						if(!vatExistInWhiltList && !exceptInvoiceList.contains(id)){
							FnaInvoiceLedger fnaInvoiceLedger = new FnaInvoiceLedger();
							fnaInvoiceLedger.setInvoiceNumber(invoiceNumber);
							fnaInvoiceLedger.setInvoiceCode(invoiceCode);
							fnaInvoiceLedger.setInvoiceType(invoiceType);
							invoiceLedgerList.add(fnaInvoiceLedger);
						}
					}
					//如果开启了其他类型发票连号控制，并且当前发票是非增值税发票
					if(otherCtrl==1 && invoiceType!=1 && invoiceType!=2 && invoiceType!=15 && invoiceType!=16 && invoiceType!=20 && invoiceType!=11){

						if(invoiceTypeList.contains(String.valueOf(invoiceType))){
							//如果当前人员不在把增值税发票连号控制白名单内,并且当前发票不在例外列表中
							if(!otherExistInWhiltList && !exceptInvoiceList.contains(id)){
								FnaInvoiceLedger fnaInvoiceLedger = new FnaInvoiceLedger();
								fnaInvoiceLedger.setInvoiceNumber(invoiceNumber);
								fnaInvoiceLedger.setInvoiceCode(invoiceCode);
								fnaInvoiceLedger.setInvoiceType(invoiceType);
								invoiceLedgerList.add(fnaInvoiceLedger);
							}
						}
					}

				}
			}
			StringBuffer serialInvoice = new StringBuffer();
            for(FnaInvoiceLedger fnaInvoiceLedger :invoiceLedgerList){
                 String invoiceNumber = fnaInvoiceLedger.getInvoiceNumber();
                 String invoiceCode = fnaInvoiceLedger.getInvoiceCode();
                 int invoiceType = fnaInvoiceLedger.getInvoiceType();
                 //可以用来判断发票是否连号的发票号码一定是数字
				 int number = 0;
				 try{
					 number = Integer.valueOf(invoiceNumber);
				 }catch (Exception e){
					 continue;
				 }
				 int beforeNumber = number - 1;
				 int afterNumber = number + 1;
				 rs.executeQuery("select id from fnaInvoiceLedger where invoiceType=? and invoiceCode=? and (invoiceNumber=? or invoiceNumber=?)",
						 invoiceType, invoiceCode, beforeNumber, afterNumber);
				 if (rs.next()) {
					 if (serialInvoice.length() == 0) {
						 serialInvoice.append(invoiceNumber);
					 } else {
						 serialInvoice.append(" ").append(invoiceNumber);
					 }
				 }


			}
			if(serialInvoice.length()>0){
				serialInvoiceJson.put("status",false);
				serialInvoiceJson.put("msg",SystemEnv.getHtmlLabelName(516385,user.getLanguage()).replace("aaaaaaaa",serialInvoice.toString()));
			}else{
				serialInvoiceJson.put("status",true);
			}
		}catch( Exception e){
			serialInvoiceJson.put("status",false);
			serialInvoiceJson.put("msg",e.getMessage());
		}
		return serialInvoiceJson;
	}


	/**
	 * 判断用户是否已经在白名单中维护了
	 * @param user
	 * @param serialInvoiceType   连号发票类型  1增值税  2其他
	 * @return
	 */
	public boolean existInWhiltList(User user,int serialInvoiceType) throws Exception {
           RecordSet rs = new RecordSet();
		   RecordSet rs2 = new RecordSet();
		   ResourceComInfo resourceComInfo = new ResourceComInfo();
		   DepartmentComInfo departmentComInfo = new DepartmentComInfo();
		   SubCompanyComInfo subCompanyComInfo = new SubCompanyComInfo();
           boolean exist = false;
           int seclevel=Util.getIntValue(user.getSeclevel());
		   String userId = String.valueOf(user.getUID());
		   String  userDepartment = String.valueOf(user.getUserDepartment());
		   String userSubCompany1 = String.valueOf(user.getUserSubCompany1());
           rs.executeQuery("select * from fnaInvoiceWhiteList where serialInvoiceType=?",serialInvoiceType);
           while (rs.next()){
           	   int orgType = Util.getIntValue(rs.getString("orgType"),0);//组织结构类型  1人力资源，2部门，3分部,4角色，5岗位，6所有人
			   String orgIds = Util.null2String(rs.getString("orgIds"));//组织结构ID
			   List<String> orgIdsList = Arrays.asList(orgIds.split(","));
			   int startSecurityLevel = Util.getIntValue(rs.getString("startSecurityLevel"),0);//开始安全级别  针对于部门、分部、角色、所有人
			   int endSecurityLevel = Util.getIntValue(rs.getString("endSecurityLevel"),0);//结束安全级别  针对于部门、分部、角色、所有人 默认值100
			   //String includeSubordinates = Util.null2String(rs.getString("includeSubordinates"));//是否包含下级，针对于部门和分部  1包含，0不含包
			   //String roleLevel = Util.null2String(rs.getString("roleLevel"));//角色级别    1部门，2分部，3总部
			   //String jobLevel = Util.null2String(rs.getString("jobLevel"));//岗位级别   1总部，2指定分部，3指定部门
			   //String jobDesignOrgIds = Util.null2String(rs.getString("jobDesignOrgIds"));//岗位指定的分部或者部门
               if(orgType==1){//人力资源
                    if(orgIdsList.contains(userId)){
						exist = true;
						break;
					}
			   }else if(orgType==2){//部门
				   if(orgIdsList.contains(userDepartment) && seclevel>=startSecurityLevel && seclevel<=endSecurityLevel){
					   exist = true;
					   break;
				   }
			   }else if(orgType==3){//分部
				   if(orgIdsList.contains(userSubCompany1) && seclevel>=startSecurityLevel && seclevel<=endSecurityLevel){
					   exist = true;
					   break;
				   }
			   }else if(orgType==6){//所有人
                    if(seclevel>=startSecurityLevel && seclevel<=endSecurityLevel){
						exist = true;
						break;
					}
			   }
		   }
		   return exist;
	}

	/**
	 * 流程上传识别发票图片
	 * @param fileids 文件fileid集合
	 * @throws Exception
	 */
	public static byte[] invoiceIdentifyFormWorkflow(String imagefileid) throws Exception{
		RecordSet rs = new RecordSet();
		//发票ids
		InputStream inputStream = ImageFileManager.getInputStreamById(Util.getIntValue(imagefileid));
		FnaInvoiceCommon fnaInvoiceCommon = new FnaInvoiceCommon();
	    String fileData = fnaInvoiceCommon.changeFileTobase64(inputStream);
	    if(fileData.contains("data:image/jpeg;base64,")){//为图片
	        fileData = fileData.replaceFirst("data:image/jpeg;base64,", "");
	    }else if(fileData.contains("data:image/png;base64,")){//为png
	        fileData = fileData.replaceFirst("data:image/png;base64,", "");
	    }else if(fileData.contains("data:image/gif;base64,")){//为gif
	        fileData = fileData.replaceFirst("data:image/gif;base64,", "");
	    }else if(fileData.contains("data:application/pdf;base64,")){//为pdf
	        fileData = fileData.replaceFirst("data:application/pdf;base64,", "");
	    }
	    byte[] imageBytes = ImageUtil.transformImage(fileData);
		return imageBytes;
	}


	/**
	 *
	 * @Title: getInvoiceIdByCheck
	 * @Description: 验票
	 * @param: @param invoiceInfo
	 * @param: @param user
	 * @param: @return
	 * @param: @throws Exception
	 * @return: String
	 * @throws
	 */
	public static JSONObject getInvoiceIdByCheck(JSONObject invoiceInfo,User user,String ipAdress) throws Exception{
		String invoiceId = "";
		String invoiceNumber = "";
		JSONObject returnObj = new JSONObject();
		try{
			RecordSet rs = new RecordSet();
			if(invoiceInfo.containsKey("invoiceId")){
				invoiceId = invoiceInfo.getString("invoiceId");
			}
			boolean isauthenticity = false;

			String invoiceCode = "";
			String priceWithoutTax = "";
			String checkcode = "";
			String billingDate = "";
			int userid_new = 0;
			String invoicestatus = "";
			String invoiceType = invoiceInfo.getString("invoiceType");
			if(!"".equals(invoiceId)){
				String authenticity = "";

				String sql = "select id,billingDate,taxIncludedPrice,invoiceType,checkCode,invoiceCode,userid_new,authenticity,invoiceNumber,status from fnaInvoiceLedger where id = ? ";
		        rs.executeQuery(sql, invoiceId);
		        if(rs.next()){
		            billingDate = Util.null2String(rs.getString("billingDate"));
		            priceWithoutTax = Util.null2String(rs.getString("taxIncludedPrice"));
		            checkcode = Util.null2String(rs.getString("checkCode"));
		            userid_new = Util.getIntValue(rs.getString("userid_new"));
		            authenticity = Util.null2String(rs.getString("authenticity"));
		            invoiceNumber = Util.null2String(rs.getString("invoiceNumber"));
		            invoiceCode = Util.null2String(rs.getString("invoiceCode"));
		            invoicestatus = Util.null2String(rs.getString("status"));
		        }
		        if("1".equals(authenticity)){
		        	isauthenticity = true;
		        }
			}else{

				JSONObject inv = invoiceInfo.getJSONObject("invoiceInfo");


				if(inv.containsKey("pretax_amount")){
					priceWithoutTax =inv.getString("pretax_amount");
				}
				if(inv.containsKey("code")){
					invoiceCode =inv.getString("code");
				}
				if(inv.containsKey("number")){
					invoiceNumber =inv.getString("number");
				}

				checkcode ="";
				if((!"10100".equals(invoiceType))&&inv.containsKey("check_code")){
					checkcode = inv.getString("check_code");
				}
				String[] invoiceData = getInvoiceData(invoiceNumber,invoiceCode);

				isauthenticity = "1".equals(invoiceData[7]);
				userid_new = Util.getIntValue(invoiceData[6]);
				invoiceId = invoiceData[3];
				billingDate = invoiceData[0];
				invoicestatus = invoiceData[8];
			}
			if("1".equals(invoicestatus)){
				throw new Exception(SystemEnv.getHtmlLabelName(383091,user.getLanguage())+"！");
			}
			if("2".equals(invoicestatus)){
				throw new Exception(SystemEnv.getHtmlLabelName(383092,user.getLanguage())+"！");
			}

			//判断此张发票是否为真
			if(isauthenticity){ //为真，判断此张发票是否可以被当前用户使用
				if(user.getUID() != userid_new && !InvoiceSharerUtil.isSharerWithoutEidtAll(invoiceId, user)){
					throw new Exception(SystemEnv.getHtmlLabelName(517367,user.getLanguage())+"！");//已被其他用户使用
				}
				returnObj.put("flag", "true");
				returnObj.put("invoiceId", invoiceId);
				returnObj.put("invoiceNumber", invoiceNumber);
				return returnObj;
			}else{ //不为真需要查验
				/** 金额格式化对象；保留两位小数*/
				DecimalFormat df = new DecimalFormat("####################################################0.00");
				FnaInvoiceCommon fnaInvoiceCommon = new FnaInvoiceCommon();
				FnaAbstractInterface fnaAbstractInterface = fnaInvoiceCommon.getInterface(user);
				String result = "";
				if("2".equals(invoiceType)){
					result = "01,01,"+invoiceCode+","+invoiceNumber+","+priceWithoutTax+","+billingDate.replace("-", "")+","+fnaInvoiceCommon.addCheckCode(checkcode)+",1111,";
				}else{
					result = "01,04,"+invoiceCode+","+invoiceNumber+","+priceWithoutTax+","+billingDate.replace("-", "")+","+fnaInvoiceCommon.addCheckCode(checkcode)+",1111,";
				}
				JSONObject resultJson = fnaAbstractInterface.scanQRCodeCheck("0", result,null);


				int status = resultJson.getInt("status");
				if(status!=0){//验票成功
					String invoiceNumberTrue = resultJson.getString("_invoiceNumber");
					String invoiceCodeTrue = resultJson.getString("_invoicecode");
					String billingDateTrue = resultJson.getString("_billingDate");
					String priceWithoutTaxTrue = resultJson.getString("_priceWithoutTax");
					String taxTrue = resultJson.getString("_tax");
					String taxIncludedPriceTrue = resultJson.getString("_taxIncludedPrice");
					String purchaserTrue = resultJson.getString("_purchaser");//1
					String sellerTrue = resultJson.getString("_seller");
					String salesTaxNoTrue = resultJson.getString("_salesTaxNo");
					String purchaserTaxNoTrue = resultJson.getString("_purchaserTaxNo");//2
					String taxRateTrue =resultJson.getString("_taxRate");

					boolean protectInvoiceTaxpayerNumber = FnaInvoiceCommon.protectInvoiceTaxpayerNumber(purchaserTrue,purchaserTaxNoTrue);
					
					String updateSql = "update FnaInvoiceLedger set   ";
					
					if(!protectInvoiceTaxpayerNumber){
						/*json.put("flag", false);
						json.put("msg", SystemEnv.getHtmlLabelName(390260,user.getLanguage()));
						return json;*/
						updateSql += " authenticity = 0,checkStatus = 3 ";
					}else {
						updateSql += " authenticity = 1,checkStatus = 1 ";
					}
					
					
					if(!"".equals(billingDateTrue)){
						updateSql += " ,billingDate = '"+StringEscapeUtils.escapeSql(billingDateTrue)+"' ";
					}
					if(!"".equals(priceWithoutTaxTrue)){
						updateSql += " ,priceWithoutTax = "+df.format(Util.getDoubleValue(priceWithoutTaxTrue,0.00));
					}
					if(!"".equals(taxTrue)){
						updateSql += " ,tax = "+df.format(Util.getDoubleValue(taxTrue,0.00));
					}
					if(!"".equals(taxIncludedPriceTrue)){
						updateSql += " ,taxIncludedPrice = "+df.format(Util.getDoubleValue(taxIncludedPriceTrue,0.00));
					}
					if(!"".equals(purchaserTrue)){
						updateSql += " ,purchaser = '"+StringEscapeUtils.escapeSql(purchaserTrue)+"' ";
					}
					if(!"".equals(sellerTrue)){
						updateSql += " ,seller = '"+StringEscapeUtils.escapeSql(sellerTrue)+"' ";
					}
					if(!"".equals(purchaserTaxNoTrue)){
						updateSql += " ,purchaserTaxNo = '"+StringEscapeUtils.escapeSql(purchaserTaxNoTrue)+"' ";
					}
					if(!"".equals(salesTaxNoTrue)){
						updateSql += " ,salesTaxNo = '"+StringEscapeUtils.escapeSql(salesTaxNoTrue)+"' ";
					}
					if(!"".equals(taxRateTrue)){
						updateSql += " ,taxRate = "+df.format(Util.getDoubleValue(taxRateTrue,0.00));
					}
					if(!"".equals(invoiceNumberTrue)){
						updateSql += " ,invoiceNumber = '"+StringEscapeUtils.escapeSql(invoiceNumberTrue)+"' ";
					}
					if(!"".equals(invoiceCodeTrue)){
						updateSql += " ,invoiceCode = '"+StringEscapeUtils.escapeSql(invoiceCodeTrue)+"' ";
					}
					updateSql += " where id = ? ";


					//添加日志
					//插入日志1
					FnaLogSqlUtil fnaLogSqlUtil = new FnaLogSqlUtil();
					Map<String, String> labelIdMap = new HashMap<String, String>();
					Map<String, String> beforeMap = fnaLogSqlUtil.getInvoiceMap(invoiceId,labelIdMap);

					rs.executeUpdate(updateSql,Util.getIntValue(invoiceId,0));
					if("10100".equals(invoiceType)||"10101".equals(invoiceType) || "10102".equals(invoiceType) || "10103".equals(invoiceType)){//增值税发票
						String remark = resultJson.getString("_remark");
						String sellerAddress = resultJson.getString("_sellerAddress");
						String purchaserAddress = resultJson.getString("_purchaserAddress");
						String salesBank = resultJson.getString("_salesBank");
						String purchaserBank = resultJson.getString("_purchaserBank");
						//保存FnaInvoiceLedgerDtl表信息
						InvoiceUtil.updateInsertFnaInvoiceLedgerDtl(1,Util.getIntValue(invoiceId,0),remark,"",sellerAddress,purchaserAddress,salesBank,purchaserBank);
						saveInvoiceLedgerDetail(resultJson.getJSONArray("detaildata"),invoiceNumberTrue,invoiceCodeTrue,user);
					}

					//插入日志2
					Map<String, String> afterMap =fnaLogSqlUtil.getInvoiceMap(invoiceId,labelIdMap);
					fnaLogSqlUtil.invoiceLedgerAddlog(user,ipAdress,"2",invoiceId,"1",
							beforeMap,afterMap,labelIdMap);

					if(!protectInvoiceTaxpayerNumber){
						throw new Exception(SystemEnv.getHtmlLabelName(390260,user.getLanguage()));
					}
				}else{
					String msg = SystemEnv.getHtmlLabelName(509478,user.getLanguage());
					if(resultJson.containsKey("errMsg")){
						msg = Util.null2String(resultJson.getString("errMsg"));
					}
					throw new Exception(msg);//查验失败
				}

			}
			returnObj.put("flag", "true");
			returnObj.put("invoiceId", invoiceId);
			returnObj.put("invoiceNumber", invoiceNumber);

		}catch(Exception e){

			returnObj.put("flag", "false");
			String msString = e.getMessage();
			new BaseBean().writeLog("msString:"+msString);
			if("".equals(msString)){
				msString = SystemEnv.getHtmlLabelName(509478,user.getLanguage());
			}
			new BaseBean().writeLog("msString:"+msString);
			returnObj.put("msg", SystemEnv.getHtmlLabelName(132211,user.getLanguage())+invoiceNumber+msString);//发票
		}

		return returnObj;
	}

	/**
	 *
	 * @Title: saveInvoiceLedgerDetail
	 * @Description: 保存发票明细
	 * @param: @param detailArray
	 * @param: @param invoiceNumber
	 * @param: @param invoiceCode
	 * @param: @throws Exception
	 * @return: void
	 * @throws
	 */
	public static void saveInvoiceLedgerDetail( JSONArray detailArray,String invoiceNumber,String invoiceCode,User user) throws Exception {
		BatchRecordSet brs = new BatchRecordSet();
		/** 金额格式化对象；保留两位小数*/
		DecimalFormat df = new DecimalFormat("####################################################0.00");
		RecordSet rs =new RecordSet();
		//查询出发票台账主表的id
		int mainid =0;
		rs.executeQuery("select id from fnaInvoiceLedger where invoiceNumber = ? and invoiceCode = ?",invoiceNumber,invoiceCode);
		if(rs.next()){
			mainid = Util.getIntValue(rs.getString("id"));
		}
		if(mainid==0){
			throw new Exception(SystemEnv.getHtmlLabelName(517370,user.getLanguage())+"!");//发票主表信息不存在
		}
        rs.executeUpdate("delete from FnaInvoiceLedgerDetail where mainid=?",mainid);
		//writeLog("-----detailArray-----detailArray-----"+detailArray);
		List<String> insertList = new ArrayList<String>();
		for(int i = 0;i<detailArray.size();i++){
			FnaInvoiceLedgerDetail fnaInvoiceLedgerDetail = new FnaInvoiceLedgerDetail();
			JSONObject detail = detailArray.getJSONObject(i);
			//数量，单价，货物或应税服务类型，金额，	税率，税额
			int unitNumber = Util.getIntValue(detail.containsKey("Quantity")?detail.getString("Quantity"):"0",1);//数量
			String originalUnitPrice =detail.containsKey("UnitPrice")?detail.getString("UnitPrice"):"0";
			double unitPrice = Util.getDoubleValue(originalUnitPrice,0.00);//单价
			String invoiceServiceYype = detail.containsKey("CommodityName")?detail.getString("CommodityName"):detail.getString("GoodsName");//货物或应税服务类型
			double priceWithoutTax = Util.getDoubleValue(detail.containsKey("Amount")?detail.getString("Amount"):detail.getString("TotalAmount"),0.00);//金额
			double taxRate = Util.getDoubleValue(detail.getString("TaxRate").toString(),0.00) * 100;//税率
			double tax = Util.getDoubleValue(detail.getString("Tax"),0.00);//税额

			insertList.add(mainid +"" + Util.getSeparator() + unitNumber+"" + Util.getSeparator() + df.format(unitPrice) + Util.getSeparator()+StringEscapeUtils.escapeSql(originalUnitPrice)+Util.getSeparator()
					+StringEscapeUtils.escapeSql(invoiceServiceYype)+ Util.getSeparator()+df.format(priceWithoutTax)+ Util.getSeparator()+df.format(taxRate)
					+ Util.getSeparator()+df.format(tax));
		}
		brs.executeSqlBatch("insert into FnaInvoiceLedgerDetail(mainid,unitNumber,unitPrice,originalUnitPrice,invoiceServiceYype,priceWithoutTax,taxRate,tax) VALUES (?,?,?,?,?,?,?,?)", insertList);

	}


	/**
	 *
	 * @Title: getInvoiceData
	 * @Description: 获取发票信息
	 * @param: @param invoiceNumber
	 * @param: @param invoiceCode
	 * @param: @return
	 * @return: String[]
	 * @throws
	 */
    public static String[] getInvoiceData(String invoiceNumber,String invoiceCode){
        RecordSet rs = new RecordSet();
        String[] data = new String[9];
        String sql = "select id,billingDate,taxIncludedPrice,invoiceType,checkCode,invoiceCode,userid_new,authenticity,status from fnaInvoiceLedger where invoiceNumber = ? and invoiceCode = ? ";
        rs.executeQuery(sql, invoiceNumber, invoiceCode);
        String id = "0";
        String billingDate = "";
        String taxIncludedPrice = "";
        String invoiceType = "";
        String checkCode = "";
        String userid_new = "";
        String authenticity = "";
        String status = "";

        if(rs.next()){
            id = Util.null2String(rs.getString("id"));
            billingDate = Util.null2String(rs.getString("billingDate"));
            taxIncludedPrice = Util.null2String(rs.getString("taxIncludedPrice"));
            invoiceType = Util.null2String(rs.getString("invoiceType"));
            checkCode = Util.null2String(rs.getString("checkCode"));
            userid_new = Util.null2String(rs.getString("userid_new"));
            authenticity = Util.null2String(rs.getString("authenticity"));
            status = Util.null2String(rs.getString("status"));
        }
        data[0] = billingDate;
        data[1] = taxIncludedPrice;
        data[2] = invoiceType;
        data[3] = id;
        data[4] = checkCode;
        data[5] = invoiceCode;
        data[6] = userid_new;
        data[7] = authenticity;
        data[8] = status;
        return data;
    }



		/**
		 * 处理in造成的sql拼接问题
		 * @param sql  例如   select * from fnaInvoiceledger where id in(占位符标识)
		 * @param ids  用英文逗号隔开
		 * @param type 类型   executeQuery   or executeUpdate
		 */
		public static RecordSet executeInSql(String sql,String ids,String type){
			RecordSet rs =new RecordSet();
			String[] ids_split = ids.split(",");
			StringBuffer idsBuffer = new StringBuffer();
			List<String> idsList = new ArrayList<>();
			for(int i=0;i<ids_split.length;i++){
				if(idsBuffer.length()==0){
					idsBuffer.append("?");
				}else{
					idsBuffer.append(",").append("?");
				}
				idsList.add(ids_split[i]);
			}
			if(idsBuffer.length()>0) {

				sql = sql.replace("占位符标识", idsBuffer.toString());
				if("executeQuery".equals(type)){
					rs.executeQuery(sql,idsList);
				}else if("executeUpdate".equals(type)){
					rs.executeUpdate(sql,idsList);
				}
			}
			return rs;
		}


	/**
	 * 通过日期获取时间戳 精确到秒
	 * @param date yyyy-MM-dd
	 * @return
	 */
	public static String getTimestamp(String date){
		String timestamp = "";
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			Date d = sdf.parse(date);
			timestamp = Util.null2String(d.getTime()/1000);
		}catch (Exception e){}
		return timestamp;
	}

}
